Berkeley DB Java Edition
version 4.1.21

com.sleepycat.je
Class LockConflictException

java.lang.Object
  extended by java.lang.Throwable
      extended by java.lang.Exception
          extended by java.lang.RuntimeException
              extended by com.sleepycat.je.DatabaseException
                  extended by com.sleepycat.je.OperationFailureException
                      extended by com.sleepycat.je.LockConflictException
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
DeadlockException, LockNotAvailableException, LockPreemptedException, LockTimeoutException, TransactionTimeoutException

public abstract class LockConflictException
extends OperationFailureException

The common base class for all exceptions that result from record lock conflicts during read and write operations.

This exception normally indicates that a transaction may be retried. Catching this exception, rather than its subclasses, is convenient and recommended for handling lock conflicts and performing transaction retries in a general purpose manner. See below for information on performing transaction retries.

The exception carrys two arrays of transaction ids, one of the owners and the other of the waiters, at the time of the lock conflict. This information may be used along with the Transaction ID for diagnosing locking problems. See getOwnerTxnIds() and getWaiterTxnIds().

The Transaction handle is invalidated as a result of this exception.

Note that in JE 3.3 and earlier, LockConflictException was not available and DeadlockException served as the common base class for lock conflict exceptions. See EnvironmentConfig.LOCK_OLD_LOCK_EXCEPTIONS for more information.

Performing Transaction Retries

If a lock conflict occurs during a transaction, the transaction may be retried by performing the following steps. Some applications may also wish to sleep for a short interval before retrying, to give other concurrent transactions a chance to finish and release their locks.

  1. Close all cursors opened under the transaction.
  2. Abort the transaction.
  3. Begin a new transaction and repeat the operations.

To handle LockConflictException reliably for all types of JE applications including JE-HA applications, it is important to handle it when it is thrown by all Database and Cursor read and write operations.

The following example code illustrates the recommended approach. Note that the Environment.beginTransaction and Transaction.commit calls are intentially inside the try block. When using JE-HA, this will make it easy to add a catch for other exceptions that can be resolved by retrying the transaction, such as consistency exceptions.

  void doTransaction(final Environment env,
                     final Database db1,
                     final Database db2,
                     final int maxTries)
      throws DatabaseException {

      boolean success = false;
      long sleepMillis = 0;
      for (int i = 0; i < maxTries; i++) {
          // Sleep before retrying.
          if (sleepMillis != 0) {
              Thread.sleep(sleepMillis);
              sleepMillis = 0;
          }
          Transaction txn = null;
          try {
              txn = env.beginTransaction(null, null);
              final Cursor cursor1 = db1.openCursor(txn, null);
              try {
                  final Cursor cursor2 = db2.openCursor(txn, null);
                  try {
                      // INSERT APP-SPECIFIC CODE HERE:
                      // Perform read and write operations.
                  } finally {
                      cursor2.close();
                  }
              } finally {
                  cursor1.close();
              }
              txn.commit();
              success = true;
              return;
          } catch (LockConflictException e) {
              sleepMillis = LOCK_CONFLICT_RETRY_SEC * 1000;
              continue;
          } finally {
              if (!success) {
                  if (txn != null) {
                      txn.abort();
                  }
              }
          }
      }
      // INSERT APP-SPECIFIC CODE HERE:
      // Transaction failed, despite retries.
      // Take some app-specific course of action.
  }

For more information on transactions and lock conflicts, see Writing Transactional Applications.

Since:
4.0
See Also:
Serialized Form

Method Summary
 long[] getOwnerTxnIds()
          Returns an array of longs containing transaction ids of owners at the the time of the timeout.
 long[] getWaiterTxnIds()
          Returns an array of longs containing transaction ids of waiters at the the time of the timeout.
 
Methods inherited from class com.sleepycat.je.DatabaseException
getMessage
 
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Method Detail

getOwnerTxnIds

public long[] getOwnerTxnIds()
Returns an array of longs containing transaction ids of owners at the the time of the timeout.

Returns:
an array of longs containing transaction ids of owners at the the time of the timeout.

getWaiterTxnIds

public long[] getWaiterTxnIds()
Returns an array of longs containing transaction ids of waiters at the the time of the timeout.

Returns:
an array of longs containing transaction ids of waiters at the the time of the timeout.

Berkeley DB Java Edition
version 4.1.21

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