com.sleepycat.je.txn
Class Locker

java.lang.Object
  extended by com.sleepycat.je.txn.Locker
Direct Known Subclasses:
BasicLocker, Txn

public abstract class Locker
extends Object

Locker instances are JE's route to locking and transactional support. This class is the abstract base class for BasicLocker, ThreadLocker, Txn, MasterTxn and ReadonlyTxn. Locker instances are in fact only a transaction shell to get to the lock manager, and don't guarantee transactional semantics. Txn (includes Txns marked autoTxn) MasterTxn and ReadonlyTxn instances are truly transactional. They have potentially different transaction begin and end behaviors.


Field Summary
protected  boolean defaultNoWait
           
protected  Map<Long,BINReference> deleteInfo
           
protected  EnvironmentImpl envImpl
           
protected  long id
           
protected  LockManager lockManager
           
protected  boolean readUncommittedDefault
           
protected  Thread thread
          The thread that created this locker.
 
Constructor Summary
(package private) Locker()
          For reading from the log.
protected Locker(EnvironmentImpl envImpl, boolean readUncommittedDefault, boolean noWait, long mandatedId)
          Create a locker id.
 
Method Summary
(package private)  void addBuddy(BuddyLocker buddy)
          By default the set of buddy lockers is not maintained.
 void addDeleteInfo(BIN bin)
          Add delete information, to be added to the inCompressor queue when the transaction ends.
protected abstract  void addLock(Long lsn, LockType type, LockGrantType grantStatus)
          Add a lock to set owned by this transaction.
 void addOpenedDatabase(Database dbHandle)
           
 boolean allowReleaseLockAfterLsnChange()
           
 void checkPreempted(Locker allowPreemptedLocker)
          Called when obtaining a lock to cause a LockPreemptedException to be thrown if a lock was preempted earlier.
protected abstract  void checkState(boolean ignoreCalledByAbort)
           
(package private)  void close()
          Should be called by all subclasses when the locker is no longer used.
abstract  StatGroup collectStats()
          Get lock count, for per transaction lock stats, for internal debugging.
abstract  boolean createdNode(long lsn)
           
 void demoteLock(long lsn)
          Revert this lock from a write lock to a read lock.
 void disallowReplicaWrite()
          Throws ReplicaWriteException if called for a locker on a Replica.
 void dumpLockTable()
          Dump lock table, for debugging
protected abstract  long generateId(TxnManager txnManager, long mandatedId)
          A Locker has to generate its next id.
 boolean getDefaultNoWait()
           
 EnvironmentImpl getEnvironment()
           
 long getId()
           
 boolean getImportunate()
          Get the state of a transaction's IMPORTUNATE bit.
protected  long getInitialLockTimeout()
           
 long getLockTimeout()
          Get the lock timeout period for this locker, in milliseconds WARNING: Be sure to always access the timeout with this accessor, since it is overridden in BuddyLocker.
 boolean getPreemptable()
          Returns whether my locks can be stolen/preemted.
 Transaction getTransaction()
          Returns a Transaction is the locker is transctional, or null otherwise.
abstract  Txn getTxnLocker()
          Returns the underlying Txn if the locker is transactional, or null if the locker is non-transactional.
(package private)  long getTxnStartMillis()
           
 long getTxnTimeout()
          Get the transaction timeout period for this locker, in milliseconds public for jca/ra/JELocalTransaction.
(package private)  Lock getWaitingFor()
           
abstract  WriteLockInfo getWriteLockInfo(long lsn)
           
(package private)  boolean isPreempted()
          For unit testing.
abstract  boolean isReadCommittedIsolation()
          Returns whether the isolation level of this locker is read-committed.
 boolean isReadUncommittedDefault()
           
 boolean isReplicationDefined()
          Used for debugging checks to ensure that replication-defined lockers are used for accessing replicated databases.
 boolean isRolledBack()
           
abstract  boolean isSerializableIsolation()
          Returns whether the isolation level of this locker is serializable.
 boolean isTimedOut()
           
abstract  boolean isTransactional()
          Returns whether this locker is transactional.
 boolean isValid()
          Used to determine whether the locker is usable.
 LockResult lock(long lsn, LockType lockType, boolean noWait, DatabaseImpl database)
          Request a blocking or non-blocking lock of the given type on the given LSN.
 void lockAfterLsnChange(long oldLsn, long newLsn, DatabaseImpl dbImpl)
          Called when an LN is logged by an operation that will not hold the lock such as eviction/checkpoint deferred-write logging or cleaner LN migration.
abstract  boolean lockingRequired()
          Returns true if locking is required for this Locker.
(package private) abstract  LockResult lockInternal(long lsn, LockType lockType, boolean noWait, boolean jumpAheadOfWaiters, DatabaseImpl database)
          Abstract method to a blocking or non-blocking lock of the given type on the given LSN.
abstract  void markDeleteAtTxnEnd(DatabaseImpl db, boolean deleteAtCommit)
          Database operations like remove and truncate leave behind residual DatabaseImpls that must be purged at transaction commit or abort.
(package private) abstract  void moveWriteToReadLock(long lsn, Lock lock)
          A lock is being demoted.
abstract  Locker newNonTxnLocker()
          Creates a fresh non-transactional locker, while retaining any transactional locks held by this locker.
 LockResult nonBlockingLock(long lsn, LockType lockType, boolean jumpAheadOfWaiters, DatabaseImpl database)
          Request a non-blocking lock of the given type on the given LSN.
abstract  void nonTxnOperationEnd()
          Releases locks and closes the locker at the end of a non-transactional cursor operation.
 void openCursorHook(DatabaseImpl dbImpl)
          Overridden to perform actions in a non-transactional cursor when it is opened, for example, ReplicaThreadLocker performs consistency checks.
 void operationEnd()
          The equivalent of calling operationEnd(true).
abstract  void operationEnd(boolean operationOK)
          Different types of transactions do different things when the operation ends.
 void operationEnd(OperationStatus status)
          A SUCCESS status equals operationOk.
abstract  void preLogWithoutLock(DatabaseImpl database)
          In the case where logging occurs before locking, we must ensure that we're prepared to undo if logging succeeds but locking fails.
abstract  void registerCursor(CursorImpl cursor)
          Tell this transaction about a cursor.
 boolean releaseLock(long lsn)
          Release the lock on this LN and remove from the transaction's owning set.
abstract  void releaseNonTxnLocks()
          Releases any non-transactional locks held by this locker.
(package private)  void removeBuddy(BuddyLocker buddy)
          By default the set of buddy lockers is not maintained.
(package private) abstract  void removeLock(long lsn)
          Remove the lock from the set owned by this transaction.
(package private)  boolean setAllowMultithreadedAccess(boolean allow)
          See ThreadLocker.allowMultithreadedAccess.
 void setClosingLocker(Locker closingLocker)
          This method is called to set the closingLocker when a cursor has been duplicated prior to being moved.
 void setImportunate(boolean importunate)
          Set the state of a transaction's IMPORTUNATE bit.
 void setLockTimeout(long timeout)
          Set the lock timeout period for any locks in this transaction, in milliseconds.
 void setOnlyAbortable(OperationFailureException cause)
          Set the state of a transaction to abort-only.
 void setPreemptable(boolean preemptable)
          Allows/disallows my locks from being stolen/preemted.
 void setPreempted()
          Called when a lock is stolen from this locker by the HA replayer.
 void setTxnTimeout(long timeout)
          Set the timeout period for this transaction, in milliseconds.
(package private)  void setWaitingFor(Lock lock)
           
 boolean sharesLocksWith(Locker other)
          Returns whether this locker can share locks with the given locker.
(package private)  void throwIfPreempted(Locker allowPreemptedLocker)
          Called by checkPreempted to cause a LockPreemptedException to be thrown if a lock was preempted earlier.
 String toString()
           
abstract  void unRegisterCursor(CursorImpl cursor)
          Remove a cursor from this txn.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

envImpl

protected EnvironmentImpl envImpl

lockManager

protected LockManager lockManager

id

protected long id

readUncommittedDefault

protected boolean readUncommittedDefault

defaultNoWait

protected boolean defaultNoWait

deleteInfo

protected Map<Long,BINReference> deleteInfo

thread

protected Thread thread
The thread that created this locker. Used for debugging, and by the ThreadLocker subclass. Note that thread may be null if the Locker is instantiated by reading the log.

Constructor Detail

Locker

protected Locker(EnvironmentImpl envImpl,
                 boolean readUncommittedDefault,
                 boolean noWait,
                 long mandatedId)
Create a locker id. This constructor is called very often, so it should be as streamlined as possible. It should never be called directly, because the mandatedId mechanism only works if the generateId() method is overridden to use the mandatedId value.

Parameters:
lockManager - lock manager for this environment
readUncommittedDefault - if true, this transaction does read-uncommitted by default
noWait - if true, non-blocking lock requests are used.

Locker

Locker()
For reading from the log.

Method Detail

getInitialLockTimeout

protected long getInitialLockTimeout()

getEnvironment

public EnvironmentImpl getEnvironment()

generateId

protected abstract long generateId(TxnManager txnManager,
                                   long mandatedId)
A Locker has to generate its next id. Some subtypes, like BasicLocker, have a single id for all instances because they are never used for recovery. Other subtypes ask the txn manager for an id or use a specific, mandated id.


getId

public long getId()
Returns:
the transaction's id.

getDefaultNoWait

public boolean getDefaultNoWait()
Returns:
the default no-wait (non-blocking) setting.

getLockTimeout

public long getLockTimeout()
Get the lock timeout period for this locker, in milliseconds WARNING: Be sure to always access the timeout with this accessor, since it is overridden in BuddyLocker.


setLockTimeout

public void setLockTimeout(long timeout)
Set the lock timeout period for any locks in this transaction, in milliseconds.

Parameters:
timeout - The timeout value for the transaction lifetime, in milliseconds. A value of 0 disables timeouts for the transaction.
Throws:
IllegalArgumentException - via Transaction.setLockTimeout

setTxnTimeout

public void setTxnTimeout(long timeout)
Set the timeout period for this transaction, in milliseconds.

Parameters:
timeout - The timeout value for the transaction lifetime, in microseconds. A value of 0 disables timeouts for the transaction.
Throws:
IllegalArgumentException - via Transaction.setLockTimeout

isReadUncommittedDefault

public boolean isReadUncommittedDefault()
Returns:
true if transaction was created with read-uncommitted as a default.

getWaitingFor

Lock getWaitingFor()

setWaitingFor

void setWaitingFor(Lock lock)

setOnlyAbortable

public void setOnlyAbortable(OperationFailureException cause)
Set the state of a transaction to abort-only. Should ONLY be called by OperationFailureException.


setImportunate

public void setImportunate(boolean importunate)
Set the state of a transaction's IMPORTUNATE bit.


getImportunate

public boolean getImportunate()
Get the state of a transaction's IMPORTUNATE bit.


setPreemptable

public void setPreemptable(boolean preemptable)
Allows/disallows my locks from being stolen/preemted.


getPreemptable

public boolean getPreemptable()
Returns whether my locks can be stolen/preemted.


setPreempted

public void setPreempted()
Called when a lock is stolen from this locker by the HA replayer.


checkPreempted

public void checkPreempted(Locker allowPreemptedLocker)
                    throws OperationFailureException
Called when obtaining a lock to cause a LockPreemptedException to be thrown if a lock was preempted earlier. This operation is split into two methods, checkPreempted and throwIfPreempted, so that Txn.checkPreempted can call throwIfPreempted for all its BuddyLockers without causing an infinite recursion. This method is overridden by BuddyLocker to forward the call to its parent buddy (the Txn), and by Txn to check all its child buddies.

Parameters:
allowPreemptedLocker - is a locker that is being closed as the result of a cursor move operation. If the operation is successful then allowPreemptedLocker will be closed, and the fact that a lock has been stolen from allowPreemptedLocker can be ignored.
Throws:
OperationFailureException

throwIfPreempted

final void throwIfPreempted(Locker allowPreemptedLocker)
                     throws OperationFailureException
Called by checkPreempted to cause a LockPreemptedException to be thrown if a lock was preempted earlier. Creating the LockPreemptedException sets the txn to abort-only.

Throws:
OperationFailureException
See Also:
checkPreempted(com.sleepycat.je.txn.Locker)

isPreempted

final boolean isPreempted()
For unit testing.


setClosingLocker

public void setClosingLocker(Locker closingLocker)
This method is called to set the closingLocker when a cursor has been duplicated prior to being moved. The new locker is informed of the old locker, so that a preempted lock taken by the old locker can be ignored. When the operation is complete, this method is called to clear the closingLocker so that a reference to the old closed locker is not held by this object. [#16513]

Parameters:
closingLocker - the old locker that will be closed if the new cursor (using this locker) is moved successfully.

setAllowMultithreadedAccess

boolean setAllowMultithreadedAccess(boolean allow)
See ThreadLocker.allowMultithreadedAccess.


checkState

protected abstract void checkState(boolean ignoreCalledByAbort)
                            throws DatabaseException
Throws:
DatabaseException

openCursorHook

public void openCursorHook(DatabaseImpl dbImpl)
Overridden to perform actions in a non-transactional cursor when it is opened, for example, ReplicaThreadLocker performs consistency checks.


isReplicationDefined

public boolean isReplicationDefined()
Used for debugging checks to ensure that replication-defined lockers are used for accessing replicated databases. Overridden by replicated-defined lockers to return true.


lockInternal

abstract LockResult lockInternal(long lsn,
                                 LockType lockType,
                                 boolean noWait,
                                 boolean jumpAheadOfWaiters,
                                 DatabaseImpl database)
                          throws LockConflictException,
                                 DatabaseException
Abstract method to a blocking or non-blocking lock of the given type on the given LSN. Unlike the lock() method, this method does not throw LockNotAvailableException and can therefore be used by nonBlockingLock to probe for a lock without the overhead of an exception stack trace.

Parameters:
lsn - is the node to lock.
lockType - is the type of lock to request.
noWait - is true to override the defaultNoWait setting. If true, or if defaultNoWait is true, throws LockNotAvailableException if the lock cannot be granted without waiting.
jumpAheadOfWaiters - grant the lock before other waiters, if any.
database - is the database containing lsn.
Throws:
LockConflictException - if a blocking lock could not be acquired.
DatabaseException

lock

public LockResult lock(long lsn,
                       LockType lockType,
                       boolean noWait,
                       DatabaseImpl database)
                throws LockNotAvailableException,
                       LockConflictException
Request a blocking or non-blocking lock of the given type on the given LSN.

Parameters:
lsn - is the node to lock.
lockType - is the type of lock to request.
noWait - is true to override the defaultNoWait setting. If true, or if defaultNoWait is true, throws LockNotAvailableException if the lock cannot be granted without waiting.
database - is the database containing lsn.
Throws:
LockNotAvailableException - if a non-blocking lock was denied.
LockConflictException - if a blocking lock could not be acquired.

nonBlockingLock

public LockResult nonBlockingLock(long lsn,
                                  LockType lockType,
                                  boolean jumpAheadOfWaiters,
                                  DatabaseImpl database)
Request a non-blocking lock of the given type on the given LSN.

Unlike lock(), this method returns LockGrantType.DENIED if the lock is denied rather than throwing LockNotAvailableException. This method should therefore not be used as the final lock for a user operation, since in that case LockNotAvailableException should be thrown for a denied lock. It is normally used only to probe for a lock internally, and other recourse is taken if the lock is denied.

Parameters:
lsn - is the node to lock.
lockType - is the type of lock to request.
jumpAheadOfWaiters - grant the lock before other waiters, if any.
database - is the database containing LSN.

releaseLock

public boolean releaseLock(long lsn)
                    throws DatabaseException
Release the lock on this LN and remove from the transaction's owning set.

Throws:
DatabaseException

demoteLock

public void demoteLock(long lsn)
                throws DatabaseException
Revert this lock from a write lock to a read lock.

Throws:
DatabaseException

lockAfterLsnChange

public void lockAfterLsnChange(long oldLsn,
                               long newLsn,
                               DatabaseImpl dbImpl)
Called when an LN is logged by an operation that will not hold the lock such as eviction/checkpoint deferred-write logging or cleaner LN migration. We must acquire a lock on the new LSN on behalf of every locker that currently holds a lock on the old LSN. Lock is non-blocking because no contention is possible on the new LSN. Because this locker is being used by multiple threads, this method may be called for a locker that has been closed or for which the lock on the old LSN has been released. Unlike other locking methods, in this case we simply return rather than report an error.


preLogWithoutLock

public abstract void preLogWithoutLock(DatabaseImpl database)
In the case where logging occurs before locking, we must ensure that we're prepared to undo if logging succeeds but locking fails.


disallowReplicaWrite

public void disallowReplicaWrite()
Throws ReplicaWriteException if called for a locker on a Replica. This implementation does nothing but is overridden by replication lockers. [#20543]


isTransactional

public abstract boolean isTransactional()
Returns whether this locker is transactional.


isSerializableIsolation

public abstract boolean isSerializableIsolation()
Returns whether the isolation level of this locker is serializable.


isReadCommittedIsolation

public abstract boolean isReadCommittedIsolation()
Returns whether the isolation level of this locker is read-committed.


getTxnLocker

public abstract Txn getTxnLocker()
Returns the underlying Txn if the locker is transactional, or null if the locker is non-transactional. For a Txn-based locker, this method returns 'this'. For a BuddyLocker, this method may return the buddy.


getTransaction

public Transaction getTransaction()
Returns a Transaction is the locker is transctional, or null otherwise.


newNonTxnLocker

public abstract Locker newNonTxnLocker()
                                throws DatabaseException
Creates a fresh non-transactional locker, while retaining any transactional locks held by this locker. This method is called when the cursor for this locker is cloned.

This method must return a locker that shares locks with this locker, e.g., a ThreadLocker.

In general, transactional lockers return 'this' when this method is called, while non-transactional lockers return a new instance.

Throws:
DatabaseException

releaseNonTxnLocks

public abstract void releaseNonTxnLocks()
                                 throws DatabaseException
Releases any non-transactional locks held by this locker. This method is called when the cursor moves to a new position or is closed.

In general, transactional lockers do nothing when this method is called, while non-transactional lockers release all locks as if operationEnd were called.

Throws:
DatabaseException

nonTxnOperationEnd

public abstract void nonTxnOperationEnd()
                                 throws DatabaseException
Releases locks and closes the locker at the end of a non-transactional cursor operation. For a transctional cursor this method should do nothing, since locks must be held until transaction end.

Throws:
DatabaseException

addBuddy

void addBuddy(BuddyLocker buddy)
By default the set of buddy lockers is not maintained. This is overridden by Txn.


removeBuddy

void removeBuddy(BuddyLocker buddy)
By default the set of buddy lockers is not maintained. This is overridden by Txn.


sharesLocksWith

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


operationEnd

public final void operationEnd()
                        throws DatabaseException
The equivalent of calling operationEnd(true).

Throws:
DatabaseException

operationEnd

public final void operationEnd(OperationStatus status)
                        throws DatabaseException
A SUCCESS status equals operationOk.

Throws:
DatabaseException

operationEnd

public abstract void operationEnd(boolean operationOK)
                           throws DatabaseException
Different types of transactions do different things when the operation ends. Txn does nothing, auto Txn commits or aborts, and BasicLocker (and its subclasses) just releases locks.

Parameters:
operationOK - is whether the operation succeeded, since that may impact ending behavior. (i.e for an auto Txn)
Throws:
DatabaseException

close

void close()
     throws DatabaseException
Should be called by all subclasses when the locker is no longer used. For Txns and auto Txns this is at commit or abort. For non-transactional lockers it is at operationEnd.

Throws:
DatabaseException

isValid

public boolean isValid()
Used to determine whether the locker is usable. FUTURE: Note that this method is overridden by Txn, and Txn.abort sets the state to closed when it begins rather than when it ends, but calls close() (the method above) when it ends. This is not ideal and deserves attention in the future.


addOpenedDatabase

public void addOpenedDatabase(Database dbHandle)
See Also:
Txn.addOpenedDatabase(com.sleepycat.je.Database)

allowReleaseLockAfterLsnChange

public boolean allowReleaseLockAfterLsnChange()
See Also:
HandleLocker.allowReleaseLockAfterLsnChange()

registerCursor

public abstract void registerCursor(CursorImpl cursor)
Tell this transaction about a cursor.


unRegisterCursor

public abstract void unRegisterCursor(CursorImpl cursor)
Remove a cursor from this txn.


lockingRequired

public abstract boolean lockingRequired()
Returns true if locking is required for this Locker. All Txnal lockers require it; most BasicLockers do not, but BasicLockers on internal dbs do.


getWriteLockInfo

public abstract WriteLockInfo getWriteLockInfo(long lsn)
Returns:
the WriteLockInfo for this node.

markDeleteAtTxnEnd

public abstract void markDeleteAtTxnEnd(DatabaseImpl db,
                                        boolean deleteAtCommit)
                                 throws DatabaseException
Database operations like remove and truncate leave behind residual DatabaseImpls that must be purged at transaction commit or abort.

Throws:
DatabaseException

addDeleteInfo

public void addDeleteInfo(BIN bin)
Add delete information, to be added to the inCompressor queue when the transaction ends.


addLock

protected abstract void addLock(Long lsn,
                                LockType type,
                                LockGrantType grantStatus)
                         throws DatabaseException
Add a lock to set owned by this transaction.

Throws:
DatabaseException

createdNode

public abstract boolean createdNode(long lsn)
Returns:
true if this transaction created this node, for a operation with transactional semantics.

removeLock

abstract void removeLock(long lsn)
                  throws DatabaseException
Remove the lock from the set owned by this transaction. If specified to LockManager.release, the lock manager will call this when its releasing a lock.

Throws:
DatabaseException

moveWriteToReadLock

abstract void moveWriteToReadLock(long lsn,
                                  Lock lock)
A lock is being demoted. Move it from the write collection into the read collection.


collectStats

public abstract StatGroup collectStats()
                                throws DatabaseException
Get lock count, for per transaction lock stats, for internal debugging.

Throws:
DatabaseException

isTimedOut

public boolean isTimedOut()

getTxnTimeout

public long getTxnTimeout()
Get the transaction timeout period for this locker, in milliseconds public for jca/ra/JELocalTransaction. WARNING: Be sure to always access the timeout with this accessor, since it is overridden in BuddyLocker.


getTxnStartMillis

long getTxnStartMillis()

isRolledBack

public boolean isRolledBack()
Returns:
if this locker has ever been rolled back.

toString

public String toString()
Overrides:
toString in class Object

dumpLockTable

public void dumpLockTable()
                   throws DatabaseException
Dump lock table, for debugging

Throws:
DatabaseException


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