com.sleepycat.je.txn
Class Txn

java.lang.Object
  extended by com.sleepycat.je.txn.Locker
      extended by com.sleepycat.je.txn.Txn
All Implemented Interfaces:
Loggable
Direct Known Subclasses:
PreparedTxn

public class Txn
extends Locker
implements Loggable

A Txn is the internal representation of a transaction created by a call to Environment.txnBegin. This class must support multi-threaded use.


Field Summary
static int ACCUMULATED_LIMIT
           
protected  long firstLoggedLsn
           
protected  long lastLoggedLsn
           
protected  ReplicationContext repContext
           
protected  java.util.Map<DatabaseId,DatabaseImpl> undoDatabases
           
 
Fields inherited from class com.sleepycat.je.txn.Locker
defaultNoWait, deleteInfo, envImpl, handleLockToHandleMap, handleToHandleLockMap, id, lockManager, readUncommittedDefault, thread
 
Constructor Summary
  Txn()
          Constructor for reading from log.
protected Txn(EnvironmentImpl envImpl, TransactionConfig config)
          Create a transaction from Environment.txnBegin.
protected Txn(EnvironmentImpl envImpl, TransactionConfig config, boolean noAPIReadLock, long mandatedId)
          This is only for use by subtypes which arbitrarily impose a transaction id value onto the transaction.
  Txn(EnvironmentImpl envImpl, TransactionConfig config, ReplicationContext repContext)
          Create a Txn for use in a unit test, where we won't need a auto Txn or a com.sleepycat.je.Transaction.
 
Method Summary
 long abort(boolean forceFlush)
          Abort this transaction.
 void abort(javax.transaction.xa.Xid xid)
           
protected  void addLock(java.lang.Long nodeId, LockType type, LockGrantType grantStatus)
          Add lock to the appropriate queue.
 void addLogInfo(long lastLsn)
          Called by the recovery manager when logging a transaction aware object.
protected  void checkState(boolean calledByAbort)
          Throw an exception if the transaction is not open.
protected  void cleanupDatabaseImpls(boolean isCommit)
          Cleanup leftover databaseImpls that are a by-product of database operations like removeDatabase(), truncateDatabase().
protected  void close(boolean isCommit)
           
 LockStats collectStats(LockStats stats)
          stats
 long commit()
          Call commit() with the default sync configuration property.
 long commit(Durability durability)
          Commit this transaction 1.
 void commit(javax.transaction.xa.Xid xid)
           
static Txn createAutoTxn(EnvironmentImpl envImpl, TransactionConfig config, boolean noAPIReadLock, ReplicationContext repContext)
           
 boolean createdNode(long nodeId)
           
static Txn createTxn(EnvironmentImpl envImpl, TransactionConfig config, ReplicationContext repContext)
           
 void dumpLog(java.lang.StringBuffer sb, boolean verbose)
          Write the object into the string buffer for log dumping.
protected  long generateId(TxnManager txnManager, long ignore)
          UserTxns get a new unique id for each instance.
 long getAbortLsn(long nodeId)
           
 Durability getCommitDurability()
          Returns the durability used for the commit operation.
 Durability getDefaultDurability()
          Returns the durability associated the transaction at the time it's first created.
 boolean getExplicitDurabilityConfigured()
           
 boolean getExplicitSyncConfigured()
           
 long getLastLsn()
          Access to last LSN.
 int getLogSize()
           
 boolean getOnlyAbortable()
          Get the state of a transaction's ONLY_ABORTABLE.
 boolean getPrepared()
           
protected  int getReplicatorNodeId()
           
 long getTransactionId()
           
 Txn getTxnLocker()
          This is a transactional locker.
 WriteLockInfo getWriteLockInfo(long nodeId)
           
 boolean isAutoTxn()
          Determines whether this is an auto transaction.
 boolean isClosed()
           
 boolean isHandleLockTransferrable()
           
 boolean isReadCommittedIsolation()
          Is read-committed isolation if so configured.
 boolean isSerializableIsolation()
          Is serializable isolation if so configured.
 boolean isSuspended()
           
 boolean isTransactional()
          Is always transactional.
 boolean logicalEquals(Loggable other)
           
 void markDeleteAtTxnEnd(DatabaseImpl dbImpl, boolean deleteAtCommit)
          Database operations like remove and truncate leave behind residual DatabaseImpls that must be purged at transaction commit or abort.
 Locker newNonTxnLocker()
          Returns 'this', since this locker holds no non-transactional locks.
 void nonTxnOperationEnd()
          Created transactions do nothing at the end of the operation.
 void operationEnd(boolean operationOK)
          Different types of transactions do different things when the operation ends.
protected  void postLogAbortHook()
          Invoked if the transaction associated with the preLogCommitHook was subsequently aborted, for example due to a lack of disk space.
protected  void postLogCommitHook()
          This hook is invoked after the commit record has been written to the log, but before write locks have been released, so that other application cannot see the changes made by the transaction.
protected  void preLogCommitHook()
          This hook is invoked before the commit of a transaction that made changes to a replicated environment.
 int prepare(javax.transaction.xa.Xid xid)
           
 void readFromLog(java.nio.ByteBuffer logBuffer, byte entryVersion)
          Initialize this object from the data in itemBuf.
 void registerCursor(CursorImpl cursor)
          Cursors operating under this transaction are added to the collection.
 void releaseNonTxnLocks()
          This locker holds no non-transactional locks.
 void setHandleLockOwner(boolean operationOK, Database dbHandle, boolean dbIsClosing)
          We're at the end of an operation.
 void setOnlyAbortable()
          Set the state of a transaction to ONLY_ABORTABLE.
 void setPrepared(boolean prepared)
           
 void setRepContext(ReplicationContext repContext)
          Different subclasses find a repContext at different times, depending on when they have the context to know whether a transaction should be replicated.
 void setSuspended(boolean suspended)
           
protected  void txnBeginHook(TransactionConfig config)
          A replicated environment introduces some new considerations when entering a transaction scope via an Environment.transactionBegin() operation.
protected  void undo()
          Rollback the changes to this txn's write locked nodes.
 void unRegisterCursor(CursorImpl cursor)
          Remove a cursor from the collection.
 void writeToLog(java.nio.ByteBuffer logBuffer)
          Serialize this object into the buffer.
 
Methods inherited from class com.sleepycat.je.txn.Locker
addDeleteInfo, addToHandleMaps, demoteLock, dumpLockTable, getDefaultNoWait, getId, getLockTimeout, getTxnTimeout, initApiReadLock, isReadUncommittedDefault, isTimedOut, lock, nonBlockingLock, operationEnd, operationEnd, releaseLock, setLockTimeout, setTxnTimeout, sharesLocksWith, toString, transferHandleLock
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

undoDatabases

protected java.util.Map<DatabaseId,DatabaseImpl> undoDatabases

lastLoggedLsn

protected long lastLoggedLsn

firstLoggedLsn

protected long firstLoggedLsn

ACCUMULATED_LIMIT

public static int ACCUMULATED_LIMIT

repContext

protected ReplicationContext repContext
Constructor Detail

Txn

public Txn()
Constructor for reading from log.


Txn

protected Txn(EnvironmentImpl envImpl,
              TransactionConfig config)
       throws DatabaseException
Create a transaction from Environment.txnBegin. Should only be used in cases where we are sure we'll set the repContext field before the transaction is ended. For example, should not be used to create standalone Txns for a unit test.

Throws:
DatabaseException

Txn

protected Txn(EnvironmentImpl envImpl,
              TransactionConfig config,
              boolean noAPIReadLock,
              long mandatedId)
       throws DatabaseException
This is only for use by subtypes which arbitrarily impose a transaction id value onto the transaction. This is done by implementing a version of Locker.generateId() which uses the proposed id.

Throws:
DatabaseException

Txn

public Txn(EnvironmentImpl envImpl,
           TransactionConfig config,
           ReplicationContext repContext)
    throws DatabaseException
Create a Txn for use in a unit test, where we won't need a auto Txn or a com.sleepycat.je.Transaction. In a real life transaction, we don't know a priori at the time of Txn construction whether the transaction needs to be replicated.

Throws:
DatabaseException
Method Detail

createTxn

public static Txn createTxn(EnvironmentImpl envImpl,
                            TransactionConfig config,
                            ReplicationContext repContext)
                     throws DatabaseException
Throws:
DatabaseException

createAutoTxn

public static Txn createAutoTxn(EnvironmentImpl envImpl,
                                TransactionConfig config,
                                boolean noAPIReadLock,
                                ReplicationContext repContext)
                         throws DatabaseException
Throws:
DatabaseException

generateId

protected long generateId(TxnManager txnManager,
                          long ignore)
UserTxns get a new unique id for each instance.

Specified by:
generateId in class Locker

getLastLsn

public long getLastLsn()
Access to last LSN.


getCommitDurability

public Durability getCommitDurability()
Returns the durability used for the commit operation. It's only available after a commit operation has been initiated.

Returns:
the durability associated with the commit, or null if the commit has not yet been initiated.

getDefaultDurability

public Durability getDefaultDurability()
Returns the durability associated the transaction at the time it's first created.

Returns:
the durability associated with the transaction at creation.

getPrepared

public boolean getPrepared()

setPrepared

public void setPrepared(boolean prepared)

setSuspended

public void setSuspended(boolean suspended)

isSuspended

public boolean isSuspended()

prepare

public int prepare(javax.transaction.xa.Xid xid)
            throws DatabaseException
Throws:
DatabaseException

commit

public void commit(javax.transaction.xa.Xid xid)
            throws DatabaseException
Throws:
DatabaseException

abort

public void abort(javax.transaction.xa.Xid xid)
           throws DatabaseException
Throws:
DatabaseException

commit

public long commit()
            throws DatabaseException
Call commit() with the default sync configuration property.

Throws:
DatabaseException

commit

public long commit(Durability durability)
            throws DatabaseException
Commit this transaction 1. Releases read locks 2. Writes a txn commit record into the log 3. Flushes the log to disk. 4. Add deleted LN info to IN compressor queue 5. Release all write locks If any step of this fails, we must convert this transaction to an abort.

Throws:
DatabaseException

abort

public long abort(boolean forceFlush)
           throws DatabaseException
Abort this transaction. Steps are: 1. Release LN read locks. 2. Write a txn abort entry to the log. This is only for log file cleaning optimization and there's no need to guarantee a flush to disk. 3. Find the last LN log entry written for this txn, and use that to traverse the log looking for nodes to undo. For each node, use the same undo logic as recovery to rollback the transaction. Note that we walk the log in order to undo in reverse order of the actual operations. For example, suppose the txn did this: delete K1/D1 (in LN 10) create K1/D1 (in LN 20) If we process LN10 before LN 20, we'd inadvertently create a duplicate tree of "K1", which would be fatal for the mapping tree. 4. Release the write lock for this LN.

Throws:
DatabaseException

undo

protected void undo()
             throws DatabaseException
Rollback the changes to this txn's write locked nodes.

Throws:
DatabaseException

addLogInfo

public void addLogInfo(long lastLsn)
                throws DatabaseException
Called by the recovery manager when logging a transaction aware object. This method is synchronized by the caller, by being called within the log latch. Record the last LSN for this transaction, to create the transaction chain, and also record the LSN in the write info for abort logic.

Throws:
DatabaseException

markDeleteAtTxnEnd

public void markDeleteAtTxnEnd(DatabaseImpl dbImpl,
                               boolean deleteAtCommit)
                        throws DatabaseException
Description copied from class: Locker
Database operations like remove and truncate leave behind residual DatabaseImpls that must be purged at transaction commit or abort.

Specified by:
markDeleteAtTxnEnd in class Locker
Parameters:
dbImpl - databaseImpl to remove
deleteAtCommit - true if this databaseImpl should be cleaned on commit, false if it should be cleaned on abort.
mb - environment memory budget.
Throws:
DatabaseException

cleanupDatabaseImpls

protected void cleanupDatabaseImpls(boolean isCommit)
                             throws DatabaseException
Cleanup leftover databaseImpls that are a by-product of database operations like removeDatabase(), truncateDatabase(). This method must be called outside the synchronization on this txn, because it calls finishDeleteProcessing, which gets the TxnManager's allTxns latch. The checkpointer also gets the allTxns latch, and within that latch, needs to synchronize on individual txns, so we must avoid a latching hiearchy conflict.

Throws:
DatabaseException

addLock

protected void addLock(java.lang.Long nodeId,
                       LockType type,
                       LockGrantType grantStatus)
                throws DatabaseException
Add lock to the appropriate queue.

Specified by:
addLock in class Locker
Throws:
DatabaseException

createdNode

public boolean createdNode(long nodeId)
                    throws DatabaseException
Specified by:
createdNode in class Locker
Returns:
true if this transaction created this node. We know that this is true if the node is write locked and has a null abort LSN.
Throws:
DatabaseException

getAbortLsn

public long getAbortLsn(long nodeId)
                 throws DatabaseException
Specified by:
getAbortLsn in class Locker
Returns:
the abortLsn for this node.
Throws:
DatabaseException

getWriteLockInfo

public WriteLockInfo getWriteLockInfo(long nodeId)
                               throws DatabaseException
Specified by:
getWriteLockInfo in class Locker
Returns:
the WriteLockInfo for this node.
Throws:
DatabaseException

isTransactional

public boolean isTransactional()
Is always transactional.

Specified by:
isTransactional in class Locker

isAutoTxn

public boolean isAutoTxn()
Determines whether this is an auto transaction.


isSerializableIsolation

public boolean isSerializableIsolation()
Is serializable isolation if so configured.

Specified by:
isSerializableIsolation in class Locker

isReadCommittedIsolation

public boolean isReadCommittedIsolation()
Is read-committed isolation if so configured.

Specified by:
isReadCommittedIsolation in class Locker

getExplicitSyncConfigured

public boolean getExplicitSyncConfigured()

getExplicitDurabilityConfigured

public boolean getExplicitDurabilityConfigured()

getTxnLocker

public Txn getTxnLocker()
This is a transactional locker.

Specified by:
getTxnLocker in class Locker

newNonTxnLocker

public Locker newNonTxnLocker()
                       throws DatabaseException
Returns 'this', since this locker holds no non-transactional locks. Since this is returned, sharing of locks is obviously supported.

Specified by:
newNonTxnLocker in class Locker
Throws:
DatabaseException

releaseNonTxnLocks

public void releaseNonTxnLocks()
                        throws DatabaseException
This locker holds no non-transactional locks.

Specified by:
releaseNonTxnLocks in class Locker
Throws:
DatabaseException

nonTxnOperationEnd

public void nonTxnOperationEnd()
                        throws DatabaseException
Created transactions do nothing at the end of the operation.

Specified by:
nonTxnOperationEnd in class Locker
Throws:
DatabaseException

operationEnd

public void operationEnd(boolean operationOK)
                  throws DatabaseException
Description copied from class: Locker
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.

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

setHandleLockOwner

public void setHandleLockOwner(boolean operationOK,
                               Database dbHandle,
                               boolean dbIsClosing)
                        throws DatabaseException
Description copied from class: Locker
We're at the end of an operation. Move this handle lock to the appropriate owner.

Specified by:
setHandleLockOwner in class Locker
Throws:
DatabaseException

registerCursor

public void registerCursor(CursorImpl cursor)
                    throws DatabaseException
Cursors operating under this transaction are added to the collection.

Specified by:
registerCursor in class Locker
Throws:
DatabaseException

unRegisterCursor

public void unRegisterCursor(CursorImpl cursor)
                      throws DatabaseException
Remove a cursor from the collection.

Specified by:
unRegisterCursor in class Locker
Throws:
DatabaseException

isHandleLockTransferrable

public boolean isHandleLockTransferrable()
Overrides:
isHandleLockTransferrable in class Locker
Returns:
true if this txn is willing to give up the handle lock to another txn before this txn ends.

collectStats

public LockStats collectStats(LockStats stats)
                       throws DatabaseException
stats

Specified by:
collectStats in class Locker
Throws:
DatabaseException

setOnlyAbortable

public void setOnlyAbortable()
Set the state of a transaction to ONLY_ABORTABLE.

Overrides:
setOnlyAbortable in class Locker

getOnlyAbortable

public boolean getOnlyAbortable()
Get the state of a transaction's ONLY_ABORTABLE.


checkState

protected void checkState(boolean calledByAbort)
                   throws DatabaseException
Throw an exception if the transaction is not open. If calledByAbort is true, it means we're being called from abort(). Caller must invoke with "this" synchronized.

Specified by:
checkState in class Locker
Throws:
DatabaseException

setRepContext

public void setRepContext(ReplicationContext repContext)
Different subclasses find a repContext at different times, depending on when they have the context to know whether a transaction should be replicated. Auto Txns set this at construction time, Txns set this when the transaction is configured, ReplicatedTxns set it when the txn commit or abort arrives.


close

protected void close(boolean isCommit)
              throws DatabaseException
Throws:
DatabaseException

isClosed

public boolean isClosed()

getReplicatorNodeId

protected int getReplicatorNodeId()

getLogSize

public int getLogSize()
Specified by:
getLogSize in interface Loggable
Returns:
number of bytes used to store this object.
See Also:
Loggable.getLogSize()

writeToLog

public void writeToLog(java.nio.ByteBuffer logBuffer)
Description copied from interface: Loggable
Serialize this object into the buffer.

Specified by:
writeToLog in interface Loggable
Parameters:
logBuffer - is the destination buffer
See Also:
Loggable.writeToLog(java.nio.ByteBuffer)

readFromLog

public void readFromLog(java.nio.ByteBuffer logBuffer,
                        byte entryVersion)
Description copied from interface: Loggable
Initialize this object from the data in itemBuf.

Specified by:
readFromLog in interface Loggable
See Also:
It's ok for FindBugs to whine about id not being synchronized.

dumpLog

public void dumpLog(java.lang.StringBuffer sb,
                    boolean verbose)
Description copied from interface: Loggable
Write the object into the string buffer for log dumping. Each object should be dumped without indentation or new lines and should be valid XML.

Specified by:
dumpLog in interface Loggable
Parameters:
sb - destination string buffer
verbose - if true, dump the full, verbose version
See Also:
Loggable.dumpLog(java.lang.StringBuffer, boolean)

getTransactionId

public long getTransactionId()
Specified by:
getTransactionId in interface Loggable
Returns:
the transaction id embedded within this loggable object. Objects that have no transaction id should return 0.
See Also:
Loggable.getTransactionId()

logicalEquals

public boolean logicalEquals(Loggable other)
Specified by:
logicalEquals in interface Loggable
Returns:
true if these two loggable items are logically the same. Used for replication testing.
See Also:
Loggable.logicalEquals(com.sleepycat.je.log.Loggable)

txnBeginHook

protected void txnBeginHook(TransactionConfig config)
                     throws DatabaseException
A replicated environment introduces some new considerations when entering a transaction scope via an Environment.transactionBegin() operation. On a Replica, the transactionBegin() operation must wait until the Replica has synched up to where it satisfies the ConsistencyPolicy that is in effect. On a Master, the transactionBegin() must wait until the Feeder has sufficient connections to ensure that it can satisfy the ReplicaAckPolicy, since if it does not, it will fail at commit() and the work done in the transaction will need to be undone. This hook provides the mechanism for implementing the above support for replicated transactions. It ignores all non-replicated transactions. The hook throws ReplicaStateException, if a Master switches to a Replica state while waiting for its Replicas connections. Changes from a Replica to a Master are handled transparently to the application. Exceptions manifest themselves as DatabaseException at the interface to minimize use of Replication based exceptions in core JE.

Parameters:
config - the transaction config that applies to the txn
Throws:
DatabaseException

preLogCommitHook

protected void preLogCommitHook()
                         throws DatabaseException
This hook is invoked before the commit of a transaction that made changes to a replicated environment. It's invoked for transactions executed on the master or replica, but is only relevant to transactions being done on the master. When invoked for a transaction on a replica the implementation just returns. The hook is invoked at a very specific point in the normal commit sequence: immediately before the commit log entry is written to the log. It represents the last chance to abort the transaction and provides an opportunity to make some final checks before allowing the commit can go ahead. Note that it should be possible to abort the transaction at the time the hook is invoked. After invocation of the "pre" hook one of the "post" hooks: postLogCommitHook or postLogAbortHook must always be invoked. Exceptions thrown by this hook result in the transaction being aborted and the exception being propagated back to the application.

Parameters:
txn - the transaction being committed
Throws:
DatabaseException - if there was a problem and that the transaction should be aborted.

postLogCommitHook

protected void postLogCommitHook()
                          throws DatabaseException
This hook is invoked after the commit record has been written to the log, but before write locks have been released, so that other application cannot see the changes made by the transaction. At this point the transaction has been committed by the Master. Exceptions thrown by this hook result in the transaction being completed on the Master, that is, locks are released, etc. and the exception is propagated back to the application.

Throws:
DatabaseException - to indicate that there was a replication related problem that needs to be communicated back to the application.

postLogAbortHook

protected void postLogAbortHook()
Invoked if the transaction associated with the preLogCommitHook was subsequently aborted, for example due to a lack of disk space. This method is responsible for any cleanup that may need to be done as a result of the abort. Note that only one of the "post" hooks (commit or abort) is invoked following the invocation of the "pre" hook.