package io.ebeaninternal.server.transaction;
import io.ebeaninternal.api.SpiTransaction;
import io.ebeaninternal.server.transaction.TransactionMap.State;
Used to store Transactions in a ThreadLocal.
/**
* Used to store Transactions in a ThreadLocal.
*/
public final class DefaultTransactionThreadLocal {
private static final ThreadLocal<TransactionMap> local = new ThreadLocal<TransactionMap>() {
@Override
protected synchronized TransactionMap initialValue() {
return new TransactionMap();
}
};
Not allowed.
/**
* Not allowed.
*/
private DefaultTransactionThreadLocal() {
}
Return the current TransactionState for a given serverName. This is for the
local thread of course.
/**
* Return the current TransactionState for a given serverName. This is for the
* local thread of course.
*/
private static TransactionMap.State getState(String serverName) {
return local.get().getStateWithCreate(serverName);
}
Set a new Transaction for this serverName and Thread.
/**
* Set a new Transaction for this serverName and Thread.
*/
public static void set(String serverName, SpiTransaction trans) {
getState(serverName).set(trans);
}
A mechanism to get the transaction out of the thread local by replacing it
with a 'proxy'.
Used for background fetching. Replaces the current transaction with a
'dummy' transaction. The current transaction is given to the background
thread so it can continue the fetch.
/**
* A mechanism to get the transaction out of the thread local by replacing it
* with a 'proxy'.
* <p>
* Used for background fetching. Replaces the current transaction with a
* 'dummy' transaction. The current transaction is given to the background
* thread so it can continue the fetch.
* </p>
*/
public static void replace(String serverName, SpiTransaction trans) {
getState(serverName).replace(trans);
}
Return the current Transaction for this serverName and Thread.
/**
* Return the current Transaction for this serverName and Thread.
*/
public static SpiTransaction get(String serverName) {
TransactionMap map = local.get();
State state = map.getState(serverName);
SpiTransaction t = (state == null) ? null : state.transaction;
if (map.isEmpty()) {
local.remove();
}
return t;
}
Commit the current transaction.
/**
* Commit the current transaction.
*/
public static void commit(String serverName) {
TransactionMap map = local.get();
State state = map.removeState(serverName);
if (state == null) {
throw new IllegalStateException("No current transaction for [" + serverName + "]");
}
state.commit();
if (map.isEmpty()) {
local.remove();
}
}
Rollback the current transaction.
/**
* Rollback the current transaction.
*/
public static void rollback(String serverName) {
TransactionMap map = local.get();
State state = map.removeState(serverName);
if (state == null) {
throw new IllegalStateException("No current transaction for [" + serverName + "]");
}
state.rollback();
if (map.isEmpty()) {
local.remove();
}
}
If the transaction has not been committed then roll it back.
Designed to be put in a finally block instead of a rollback() in each catch
block.
Ebean.beginTransaction();
try {
// ... perform some actions in a single transaction
Ebean.commitTransaction();
} finally {
// ensure transaction ended. If some error occurred then rollback()
Ebean.endTransaction();
}
/**
* If the transaction has not been committed then roll it back.
* <p>
* Designed to be put in a finally block instead of a rollback() in each catch
* block.
* <p>
* <pre>
* Ebean.beginTransaction();
* try {
* // ... perform some actions in a single transaction
*
* Ebean.commitTransaction();
*
* } finally {
* // ensure transaction ended. If some error occurred then rollback()
* Ebean.endTransaction();
* }
* </pre>
*/
public static void end(String serverName) {
TransactionMap map = local.get();
State state = map.removeState(serverName);
if (state != null) {
state.end();
}
if (map.isEmpty()) {
local.remove();
}
}
}