LockConflictException (Oracle - Berkeley DB Java Edition API)
Date: 2014-12-16

com.sleepycat.je

## Class LockConflictException

- java.lang.Object
- - java.lang.Throwable
  - - java.lang.Exception
    - - java.lang.RuntimeException
      - - com.sleepycat.je.DatabaseException
        - - com.sleepycat.je.OperationFailureException
          - - 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 carries 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

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `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

      `addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, getSuppressed, 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.

Copyright (c) 2004, 2014 Oracle and/or its affiliates. All rights reserved.