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.
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 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.
|
getMessage
public long[] getOwnerTxnIds()
public long[] getWaiterTxnIds()
Copyright (c) 2002, 2017 Oracle and/or its affiliates. All rights reserved.