/** * Obtain container level intent lock. * * <p>This implementation of row locking is 2 level, ie. table and row locking. It will interact * correctly with tables opened with ContainerLocking3 locking mode. * * <p>Updater's will get table level IX locks, and X row locks. * * <p>Reader's will get table level IS locks, and S row locks. * * <p>Read locks are put in a separate "group" from the transaction, so that when the container is * closed it can release these read locks. * * @param t Transaction to associate lock with. * @param container Container to lock. * @param waitForLock Should lock request wait until granted? * @param forUpdate Should container be locked for update, or read? * @return true if the lock was obtained, false if it wasn't. False should only be returned if the * waitForLock policy was set to "false," and the lock was unavailable. * @exception StandardException Standard exception policy. */ public boolean lockContainer( Transaction t, ContainerHandle container, boolean waitForLock, boolean forUpdate) throws StandardException { Object qualifier = forUpdate ? ContainerLock.CIX : ContainerLock.CIS; // for cursor stability put read locks on a separate lock chain, which // will be released when the container is unlocked. Object group = forUpdate ? ((Object) t) : ((Object) container.getUniqueId()); boolean gotLock = lf.lockObject( t.getCompatibilitySpace(), group, container.getId(), qualifier, waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT); if (gotLock) { // look for covering table locks // CIS and CIX is covered by CX // In that case move the lock to the transaction list from the // container list, as the null locking policy will do nothing in // unlockContainer(). // if (lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CX)) { // release any container group locks becuase CX container lock will cover everthing. lf.unlockGroup(t.getCompatibilitySpace(), container.getUniqueId()); container.setLockingPolicy(NO_LOCK); } else if ((!forUpdate) && lf.isLockHeld(t.getCompatibilitySpace(), t, container.getId(), ContainerLock.CS)) { // move locks from container group to transaction group. lf.transfer(t.getCompatibilitySpace(), group, t); container.setLockingPolicy(NO_LOCK); } } return gotLock; }
/** * Obtain lock on record being read. * * <p>Assumes that a table level IS has been acquired. Will acquire a Shared or Update lock on the * row, depending on the "forUpdate" parameter. * * <p>Read lock will be placed on separate group from transaction. * * @param t The transaction to associate the lock with. * @param record The record to be locked. * @param waitForLock Should lock request wait until granted? * @param forUpdate Whether to open for read or write access. * @return true if the lock was granted, false if waitForLock was false and the lock could not be * granted. * @exception StandardException Standard exception policy. */ public boolean lockRecordForRead( Transaction t, ContainerHandle container_handle, RecordHandle record, boolean waitForLock, boolean forUpdate) throws StandardException { Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2; return (lf.lockObject( t.getCompatibilitySpace(), container_handle.getUniqueId(), record, qualifier, waitForLock ? C_LockFactory.TIMED_WAIT : C_LockFactory.NO_WAIT)); }
public void unlockRecordAfterRead( Transaction t, ContainerHandle container_handle, RecordHandle record, boolean forUpdate, boolean row_qualified) throws StandardException { Object qualifier = forUpdate ? RowLock.RU2 : RowLock.RS2; int count = lf.unlock(t.getCompatibilitySpace(), container_handle.getUniqueId(), record, qualifier); if (SanityManager.DEBUG) { // in the case of lock escalation the count could be 0. if (!(count == 1 || count == 0)) { SanityManager.THROWASSERT( "count = " + count + "record.getContainerId() = " + record.getContainerId()); } } }
/** * Unlock read locks. * * <p>In Cursor stability release all read locks obtained. unlockContainer() will be called when * the container is closed. * * <p> * * @param t The transaction to associate the lock with. * @param container_handle Container to unlock. */ public void unlockContainer(Transaction t, ContainerHandle container_handle) { // Only release read locks before end of transaction in level 2. lf.unlockGroup(t.getCompatibilitySpace(), container_handle.getUniqueId()); }