Interface Transaction

All Superinterfaces:
Flushable

public interface Transaction extends Flushable
Defines a logical unit of work. Transaction instances can only be safely used by one thread at a time, and they must be reset when no longer needed. Instances can be exchanged by threads, as long as a happens-before relationship is established. Without proper exclusion, multiple threads interacting with a Transaction instance may cause database corruption.

Transactions also contain various methods for directly controlling locks, although their use is not required. Methods which operate upon transactions acquire and release locks automatically. Direct control over locks is provided for advanced use cases. One such use is record filtering:

Transaction txn = ...
Cursor c = index.newCursor(txn);
for (LockResult result = c.first(); c.key() != null; result = c.next()) {
    if (shouldDiscard(c.value()) && result == LockResult.ACQUIRED) {
        // Unlock record which doesn't belong in the transaction.
        txn.unlock();
        continue;
    }
    ...
}

Note: Transaction instances are never fully closed after they are reset or have fully exited. Any operation which acts upon a reset transaction can resurrect it.

See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final Transaction
    Transaction instance which isn't a transaction at all.
  • Method Summary

    Modifier and Type
    Method
    Description
    default void
    Attach an arbitrary object to this transaction instance, for tracking it.
    default void
    Attach a commit callback to this transaction instance, in place of an ordinary attachment.
    default Object
    Returns any attachment which was set earlier.
    void
    Checks the validity of the transaction.
    void
    Commits all modifications made within the current transaction scope.
    void
    Commits and exits all transaction scopes.
    Returns the durability mode of this transaction.
    void
    Sets the durability mode for the entire transaction, not just the current scope.
    void
    Enters a nested transaction scope, which begins with the UPGRADABLE_READ lock mode.
    void
    Exits the current transaction scope, rolling back all uncommitted modifications made within.
    void
    Manually flush all buffered changes made by this transaction to the shared redo log.
    default long
    id()
    Returns the currently assigned identifier for this transaction, which is zero when the transaction cannot replicate.
    boolean
     
    boolean
    Returns true if the current transaction scope is nested.
    long
    Returns the index id of the last lock acquired, within the current scope.
    byte[]
    Returns the key of the last lock acquired, within the current scope.
    lockCheck(long indexId, byte[] key)
    Checks the lock ownership for the given key.
    lockExclusive(long indexId, byte[] key)
    Attempts to acquire an exclusive lock for the given key, denying any additional locks.
    lockExclusive(long indexId, byte[] key, long nanosTimeout)
    Attempts to acquire an exclusive lock for the given key, denying any additional locks.
    Returns the current lock mode.
    void
    Sets the lock mode for the current scope.
    lockShared(long indexId, byte[] key)
    Attempts to acquire a shared lock for the given key, denying exclusive locks.
    lockShared(long indexId, byte[] key, long nanosTimeout)
    Attempts to acquire a shared lock for the given key, denying exclusive locks.
    void
    lockTimeout(long timeout, TimeUnit unit)
    Sets the lock timeout for the current scope.
    long
    Returns the current lock timeout, in the given unit.
    lockUpgradable(long indexId, byte[] key)
    Attempts to acquire an upgradable lock for the given key, denying exclusive and additional upgradable locks.
    lockUpgradable(long indexId, byte[] key, long nanosTimeout)
    Attempts to acquire an upgradable lock for the given key, denying exclusive and additional upgradable locks.
    int
    Counts the current transaction scope nesting level.
    void
    Exits all transaction scopes, rolling back all uncommitted modifications.
    void
    Reset the transaction due to the given cause.
    void
    Rollback all uncommitted changes within the current transaction scope.
    tryLockExclusive(long indexId, byte[] key, long nanosTimeout)
    Attempts to acquire an exclusive lock for the given key, denying any additional locks.
    tryLockShared(long indexId, byte[] key, long nanosTimeout)
    Attempts to acquire a shared lock for the given key, denying exclusive locks.
    tryLockUpgradable(long indexId, byte[] key, long nanosTimeout)
    Attempts to acquire an upgradable lock for the given key, denying exclusive and additional upgradable locks.
    void
    Fully releases the last lock or group acquired, within the current scope.
    void
    Combines the last lock acquired or upgraded into a group which can be unlocked together.
    void
    Releases the last lock or group acquired, within the current scope, retaining a shared lock.
    boolean
    wasAcquired(long indexId, byte[] key)
    Checks if the last acquired lock was against the given index id and key.
  • Field Details

    • BOGUS

      static final Transaction BOGUS
      Transaction instance which isn't a transaction at all. It always operates in an unsafe lock mode and a no-redo durability mode. For safe auto-commit transactions, pass null for the transaction argument.
  • Method Details

    • lockMode

      void lockMode(LockMode mode)
      Sets the lock mode for the current scope. Transactions begin in UPGRADABLE_READ mode, as do newly entered scopes. Exiting a scope reverts the lock mode.
      Parameters:
      mode - new lock mode
      Throws:
      IllegalArgumentException - if mode is null
    • lockMode

      LockMode lockMode()
      Returns the current lock mode.
    • lockTimeout

      void lockTimeout(long timeout, TimeUnit unit)
      Sets the lock timeout for the current scope. A negative timeout is infinite.
      Parameters:
      unit - required unit if timeout is more than zero
    • lockTimeout

      long lockTimeout(TimeUnit unit)
      Returns the current lock timeout, in the given unit.
    • durabilityMode

      void durabilityMode(DurabilityMode mode)
      Sets the durability mode for the entire transaction, not just the current scope. The durability mode primarily affects commit behavior at the top-level scope, but it can also be used to switch redo logging behavior.

      Note: This method is intended for advanced use cases.

      Parameters:
      mode - new durability mode
      Throws:
      IllegalArgumentException - if mode is null
    • durabilityMode

      DurabilityMode durabilityMode()
      Returns the durability mode of this transaction.
    • check

      void check() throws DatabaseException
      Checks the validity of the transaction.
      Throws:
      InvalidTransactionException - if transaction is broken or was invalidated by an earlier exception
      IllegalStateException - if transaction is bogus
      DatabaseException
    • isBogus

      boolean isBogus()
    • commit

      void commit() throws IOException
      Commits all modifications made within the current transaction scope. The current scope is still valid after this method is called, unless an exception is thrown. Call exit or reset to fully release transaction resources.
      Throws:
      IOException
      See Also:
    • commitAll

      void commitAll() throws IOException
      Commits and exits all transaction scopes.
      Throws:
      IOException
      See Also:
    • enter

      void enter() throws IOException
      Enters a nested transaction scope, which begins with the UPGRADABLE_READ lock mode.
      Throws:
      IOException
      See Also:
    • exit

      void exit() throws IOException
      Exits the current transaction scope, rolling back all uncommitted modifications made within. The transaction is still valid after this method is called, unless an exception is thrown.
      Throws:
      IOException
    • reset

      void reset() throws IOException
      Exits all transaction scopes, rolling back all uncommitted modifications. Equivalent to:
      while (txn.isNested()) {
          txn.exit();
      }
      txn.exit();
      
      Throws:
      IOException
    • reset

      void reset(Throwable cause)
      Reset the transaction due to the given cause. This provides an opportunity to prevent this transaction from being used any further. No exception is thrown when invoking this method.
      Parameters:
      cause - pass a cause to reset and disable the transaction; pass null to simply reset the transaction and ignore any exception when doing so
    • rollback

      void rollback() throws IOException
      Rollback all uncommitted changes within the current transaction scope. The transaction is still valid after this method is called, unless an exception is thrown.
      Throws:
      IOException
    • lockShared

      LockResult lockShared(long indexId, byte[] key) throws LockFailureException
      Attempts to acquire a shared lock for the given key, denying exclusive locks. If return value is owned, transaction already owns a strong enough lock, and no extra unlock should be performed.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      Returns:
      ACQUIRED, OWNED_SHARED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE
      Throws:
      IllegalStateException - if too many shared locks
      LockFailureException - if interrupted or timed out
      DeadlockException - if deadlock was detected after waiting the full timeout
    • lockUpgradable

      LockResult lockUpgradable(long indexId, byte[] key) throws LockFailureException
      Attempts to acquire an upgradable lock for the given key, denying exclusive and additional upgradable locks. If return value is owned, transaction already owns a strong enough lock, and no extra unlock should be performed.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      Returns:
      ACQUIRED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE
      Throws:
      LockFailureException - if interrupted, timed out, or illegal upgrade
      DeadlockException - if deadlock was detected after waiting the full timeout
    • lockExclusive

      LockResult lockExclusive(long indexId, byte[] key) throws LockFailureException
      Attempts to acquire an exclusive lock for the given key, denying any additional locks. If return value is owned, transaction already owns exclusive lock, and no extra unlock should be performed.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      Returns:
      ACQUIRED, UPGRADED, or OWNED_EXCLUSIVE
      Throws:
      LockFailureException - if interrupted, timed out, or illegal upgrade
      DeadlockException - if deadlock was detected after waiting the full timeout
    • isNested

      boolean isNested()
      Returns true if the current transaction scope is nested.
    • nestingLevel

      int nestingLevel()
      Counts the current transaction scope nesting level. Count is zero if non-nested.
    • tryLockShared

      LockResult tryLockShared(long indexId, byte[] key, long nanosTimeout) throws DeadlockException, LockFailureException
      Attempts to acquire a shared lock for the given key, denying exclusive locks. If return value is owned, transaction already owns a strong enough lock, and no extra unlock should be performed.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      nanosTimeout - maximum time to wait for lock; negative timeout is infinite
      Returns:
      INTERRUPTED, TIMED_OUT_LOCK, ACQUIRED, OWNED_SHARED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE
      Throws:
      IllegalStateException - if too many shared locks
      DeadlockException - if deadlock was detected after waiting the full timeout, unless the timeout is zero
      LockFailureException
    • lockShared

      LockResult lockShared(long indexId, byte[] key, long nanosTimeout) throws LockFailureException
      Attempts to acquire a shared lock for the given key, denying exclusive locks. If return value is owned, transaction already owns a strong enough lock, and no extra unlock should be performed.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      nanosTimeout - maximum time to wait for lock; negative timeout is infinite
      Returns:
      ACQUIRED, OWNED_SHARED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE
      Throws:
      IllegalStateException - if too many shared locks
      LockFailureException - if interrupted or timed out
      DeadlockException - if deadlock was detected after waiting the full timeout
    • tryLockUpgradable

      LockResult tryLockUpgradable(long indexId, byte[] key, long nanosTimeout) throws DeadlockException, LockFailureException
      Attempts to acquire an upgradable lock for the given key, denying exclusive and additional upgradable locks. If return value is owned, transaction already owns a strong enough lock, and no extra unlock should be performed. If ILLEGAL is returned, transaction holds a shared lock, which cannot be upgraded.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      nanosTimeout - maximum time to wait for lock; negative timeout is infinite
      Returns:
      ILLEGAL, INTERRUPTED, TIMED_OUT_LOCK, ACQUIRED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE
      Throws:
      DeadlockException - if deadlock was detected after waiting the full timeout, unless the timeout is zero
      LockFailureException
    • lockUpgradable

      LockResult lockUpgradable(long indexId, byte[] key, long nanosTimeout) throws LockFailureException
      Attempts to acquire an upgradable lock for the given key, denying exclusive and additional upgradable locks. If return value is owned, transaction already owns a strong enough lock, and no extra unlock should be performed.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      nanosTimeout - maximum time to wait for lock; negative timeout is infinite
      Returns:
      ACQUIRED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE
      Throws:
      LockFailureException - if interrupted, timed out, or illegal upgrade
      DeadlockException - if deadlock was detected after waiting the full timeout
    • tryLockExclusive

      LockResult tryLockExclusive(long indexId, byte[] key, long nanosTimeout) throws DeadlockException, LockFailureException
      Attempts to acquire an exclusive lock for the given key, denying any additional locks. If return value is owned, transaction already owns exclusive lock, and no extra unlock should be performed. If ILLEGAL is returned, transaction holds a shared lock, which cannot be upgraded.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      nanosTimeout - maximum time to wait for lock; negative timeout is infinite
      Returns:
      ILLEGAL, INTERRUPTED, TIMED_OUT_LOCK, ACQUIRED, UPGRADED, or OWNED_EXCLUSIVE
      Throws:
      DeadlockException - if deadlock was detected after waiting the full timeout, unless the timeout is zero
      LockFailureException
    • lockExclusive

      LockResult lockExclusive(long indexId, byte[] key, long nanosTimeout) throws LockFailureException
      Attempts to acquire an exclusive lock for the given key, denying any additional locks. If return value is owned, transaction already owns exclusive lock, and no extra unlock should be performed.

      Note: This method is intended for advanced use cases.

      Parameters:
      key - non-null key to lock; instance is not cloned and so it must not be modified after calling this method
      nanosTimeout - maximum time to wait for lock; negative timeout is infinite
      Returns:
      ACQUIRED, UPGRADED, or OWNED_EXCLUSIVE
      Throws:
      LockFailureException - if interrupted, timed out, or illegal upgrade
      DeadlockException - if deadlock was detected after waiting the full timeout
    • lockCheck

      LockResult lockCheck(long indexId, byte[] key)
      Checks the lock ownership for the given key.

      Note: This method is intended for advanced use cases.

      Returns:
      UNOWNED, OWNED_SHARED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE
    • lastLockedIndex

      long lastLockedIndex()
      Returns the index id of the last lock acquired, within the current scope.

      Note: This method is intended for advanced use cases.

      Returns:
      locked index id, 0 if no locks are held
    • lastLockedKey

      byte[] lastLockedKey()
      Returns the key of the last lock acquired, within the current scope.

      Note: This method is intended for advanced use cases.

      Returns:
      locked key (not cloned), or null if no locks are held
    • wasAcquired

      boolean wasAcquired(long indexId, byte[] key)
      Checks if the last acquired lock was against the given index id and key.

      Note: This method is intended for advanced use cases.

      Returns:
      true if lock matches and was just acquired
    • unlock

      void unlock()
      Fully releases the last lock or group acquired, within the current scope. If the last lock operation was an upgrade, for a lock not immediately acquired, unlock is not allowed. Instead, an IllegalStateException is thrown.

      Note: This method is intended for advanced use cases.

      Throws:
      IllegalStateException - if no locks are held, or if unlocking an exclusive lock, or if crossing a scope boundary, or if unlocking a non-immediate upgrade
    • unlockToShared

      void unlockToShared()
      Releases the last lock or group acquired, within the current scope, retaining a shared lock. If the last lock operation was an upgrade, for a lock not immediately acquired, unlock is not allowed. Instead, an IllegalStateException is thrown.

      Note: This method is intended for advanced use cases.

      Throws:
      IllegalStateException - if no locks are held, or if unlocking an exclusive lock, or if crossing a scope boundary, or if too many shared locks, or if unlocking a non-immediate upgrade
    • unlockCombine

      void unlockCombine()
      Combines the last lock acquired or upgraded into a group which can be unlocked together.

      Note: This method is intended for advanced use cases.

      Throws:
      IllegalStateException - if combining an acquire with an upgrade
    • id

      default long id()
      Returns the currently assigned identifier for this transaction, which is zero when the transaction cannot replicate. After the transaction has finished, a new identifier is generated when requested again.
      Returns:
      a positive transaction identifier, or zero if transaction cannot replicate
    • attach

      default void attach(Object obj)
      Attach an arbitrary object to this transaction instance, for tracking it. Attachments can become visible to other threads as a result of a LockTimeoutException. A happens-before relationship is guaranteed only if the attachment is set before the associated lock is acquired. Also, the LockTimeoutException constructor calls toString on the attachment, and includes it in the message. A non-default toString implementation must consider thread-safety.
      Parameters:
      obj - the object to be attached; may be null
      Throws:
      UnsupportedOperationException - if completely unsupported by the transaction implementation
    • attach

      default void attach(CommitCallback callback)
      Attach a commit callback to this transaction instance, in place of an ordinary attachment. It behaves like an ordinary attachment, but it also receives special attention by pending transactions.
      Throws:
      UnsupportedOperationException - if completely unsupported by the transaction implementation
    • attachment

      default Object attachment()
      Returns any attachment which was set earlier.
      Returns:
      the current attachment, or null if none
    • flush

      void flush() throws IOException
      Manually flush all buffered changes made by this transaction to the shared redo log. Flushing is performed automatically when the buffer fills up, or when the transaction is committed. Flushing can be used in conjunction with replication, to ensure that locks and changes are visible to replicas before the transaction commits.
      Specified by:
      flush in interface Flushable
      Throws:
      IOException