com.sleepycat.je.txn
Class HandleLocker

java.lang.Object
  extended by com.sleepycat.je.txn.Locker
      extended by com.sleepycat.je.txn.BasicLocker
          extended by com.sleepycat.je.txn.HandleLocker

public class HandleLocker
extends BasicLocker

Extends BasicLocker to share locks with another Locker that is being used to open a database. HandleLocker holds a read lock on the NameLN for the Database object, to prevent rename, removal or truncation of a database while it is open. The HandleLocker and the Locker used to open the database both hold a NameLN lock at the same time, so they must share locks to avoid conflicts. Accounts for the fact that the Txn may end before this locker ends by only keeping the Txn ID rather than a reference to the Txn object. A reference to a non-tnxl Locker is OK, OTOH, because it is short lived. Handle Locking Overview ------------------------ Environment.openDatabase calls Environment.setupDatabase, which calls Database.initHandleLocker to create the HandleLocker. setupDatabase ensures that the HandleLocker is passed to DbTree.getDb and createDb. These latter methods acquire a read lock on the NameLN for the HandleLocker, in addition to acquiring a read or write lock for the openDatabase locker. If setupDatabase is not successful, it ensures that locks are released via HandleLocker.endOperation. If setupDatabase is successful, the handle is returned by openDatabase, and Database.close must be called to release the lock. The handle lock is released by calling HandleLocker.endOperation. A special case is when a user txn is passed to openDatabase. If the txn aborts, the Database handle must be invalidated. When setupDatabase succeeds it passes the handle to Txn.addOpenedDatabase, which remembers the handle. Txn.abort invalidates the handle. NameLN Migration and LSN Changes [#20617] ----------------------------------------- When the log cleaner migrates a NameLN, its LSN changes and the new LSN is locked on behalf of all existing lockers by CursorImpl.lockAfterLsnChange. lockAfterLsnChange is also used when a dirty deferred-write LN is logged by BIN.logDirtyLN, as part of flushing a BIN during a checkpoint or eviction. Because handle lockers are legitimately very long lived, it is important that lockAfterLsnChange releases the locks on the old LSN, to avoid a steady accumulation of locks in a HandleLocker. Therefore, lockAfterLsnChange will release the lock on the old LSN, for HandleLockers only. Although it may be desirable to release the old LSN lock on other long lived lockers, it is too risky. In an experiment, this caused problems with demotion and upgrade, when a lock being demoted or upgraded was released. Because LSNs can change, it is also important that we don't rely on a single NameLN locker ID (LSN) as a data structure key for handle locks. This was acceptable when a stable Node ID was used as a lock ID, but is no longer appropriate now that mutable LSNs are used as lock IDs.


Field Summary
 
Fields inherited from class com.sleepycat.je.txn.Locker
defaultNoWait, deleteInfo, envImpl, id, lockManager, readUncommittedDefault, thread
 
Constructor Summary
protected HandleLocker(EnvironmentImpl env, Locker buddy)
          Creates a HandleLocker.
 
Method Summary
 boolean allowReleaseLockAfterLsnChange()
          Because handle lockers are legitimately very long lived, it is important that lockAfterLsnChange releases the locks on the old LSN, to avoid a steady accumulation of locks in a HandleLocker
static HandleLocker createHandleLocker(EnvironmentImpl env, Locker buddy)
           
 boolean sharesLocksWith(Locker other)
          Returns whether this locker can share locks with the given locker.
 
Methods inherited from class com.sleepycat.je.txn.BasicLocker
addLock, checkState, collectStats, createBasicLocker, createBasicLocker, createdNode, generateId, getTxnLocker, getWriteLockInfo, getWriteOwnerLocker, isReadCommittedIsolation, isSerializableIsolation, isTransactional, lockingRequired, lockInternal, markDeleteAtTxnEnd, moveWriteToReadLock, newNonTxnLocker, nonTxnOperationEnd, operationEnd, preLogWithoutLock, registerCursor, releaseNonTxnLocks, removeLock, unRegisterCursor
 
Methods inherited from class com.sleepycat.je.txn.Locker
addBuddy, addDeleteInfo, addOpenedDatabase, checkPreempted, close, demoteLock, disallowReplicaWrite, dumpLockTable, getDefaultNoWait, getEnvironment, getId, getImportunate, getInitialLockTimeout, getLockTimeout, getPreemptable, getTransaction, getTxnStartMillis, getTxnTimeout, getWaitingFor, isPreempted, isReadUncommittedDefault, isReplicationDefined, isRolledBack, isTimedOut, isValid, lock, lockAfterLsnChange, nonBlockingLock, openCursorHook, operationEnd, operationEnd, releaseLock, removeBuddy, setAllowMultithreadedAccess, setClosingLocker, setImportunate, setLockTimeout, setOnlyAbortable, setPreemptable, setPreempted, setTxnTimeout, setWaitingFor, throwIfPreempted, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

HandleLocker

protected HandleLocker(EnvironmentImpl env,
                       Locker buddy)
Creates a HandleLocker.

Method Detail

createHandleLocker

public static HandleLocker createHandleLocker(EnvironmentImpl env,
                                              Locker buddy)
                                       throws DatabaseException
Throws:
DatabaseException

sharesLocksWith

public boolean sharesLocksWith(Locker other)
Returns whether this locker can share locks with the given locker.

Overrides:
sharesLocksWith in class Locker

allowReleaseLockAfterLsnChange

public boolean allowReleaseLockAfterLsnChange()
Because handle lockers are legitimately very long lived, it is important that lockAfterLsnChange releases the locks on the old LSN, to avoid a steady accumulation of locks in a HandleLocker

Overrides:
allowReleaseLockAfterLsnChange in class Locker
See Also:
allowReleaseLockAfterLsnChange()


Copyright (c) 2004-2012 Oracle. All rights reserved.