public abstract class LockConflictException extends OperationFailureException
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.
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.
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.
Modifier | Constructor and Description |
---|---|
protected |
LockConflictException(com.sleepycat.je.txn.Locker locker,
String message)
For internal use only.
|
protected |
LockConflictException(com.sleepycat.je.txn.Locker locker,
String message,
Throwable cause)
For internal use only.
|
protected |
LockConflictException(String message,
OperationFailureException cause)
For internal use only.
|
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 |
getTimeoutMillis() |
long[] |
getWaiterTxnIds()
Returns an array of longs containing transaction ids of waiters at the
the time of the timeout.
|
void |
setOwnerTxnIds(long[] ownerTxnIds) |
void |
setTimeoutMillis(long timeoutMillis) |
void |
setWaiterTxnIds(long[] waiterTxnIds) |
wrapSelf
addErrorMessage, addRethrownStackTrace, getMessage, getVersionHeader
addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
protected LockConflictException(com.sleepycat.je.txn.Locker locker, String message)
protected LockConflictException(com.sleepycat.je.txn.Locker locker, String message, Throwable cause)
protected LockConflictException(String message, OperationFailureException cause)
public void setOwnerTxnIds(long[] ownerTxnIds)
public long[] getOwnerTxnIds()
public void setWaiterTxnIds(long[] waiterTxnIds)
public long[] getWaiterTxnIds()
public void setTimeoutMillis(long timeoutMillis)
public long getTimeoutMillis()
Copyright (c) 2002, 2015 Oracle and/or its affiliates. All rights reserved.