package org.multiverse.stms.gamma;
import org.multiverse.api.*;
import org.multiverse.api.exceptions.*;
import org.multiverse.api.callables.*;
import org.multiverse.stms.gamma.transactions.*;
import java.util.concurrent.Callable;
import java.util.logging.Logger;
import static java.lang.String.format;
import static org.multiverse.api.TxnThreadLocal.*;
/**
* The {@link TxnExecutor} made for the GammaStm.
*
* This code is generated.
*
* @author Peter Veentjer
*/
public final class FatGammaTxnExecutor extends AbstractGammaTxnExecutor{
private static final Logger logger = Logger.getLogger(FatGammaTxnExecutor.class.getName());
private final PropagationLevel propagationLevel;
public FatGammaTxnExecutor(final GammaTxnFactory txnFactory) {
super(txnFactory);
this.propagationLevel = txnConfig.propagationLevel;
}
@Override
public GammaTxnFactory getTxnFactory(){
return txnFactory;
}
@Override
public final <E> E executeChecked(
final TxnCallable<E> callable)throws Exception{
try{
return execute(callable);
}catch(InvisibleCheckedException e){
throw e.getCause();
}
}
public <E> E execute(final TxnCallable<E> callable){
if(callable == null){
throw new NullPointerException();
}
TxnThreadLocal.Container transactionContainer = getThreadLocalTxnContainer();
GammaTxnPool pool = (GammaTxnPool) transactionContainer.txPool;
if (pool == null) {
pool = new GammaTxnPool();
transactionContainer.txPool = pool;
}
GammaTxn tx = (GammaTxn)transactionContainer.txn;
if(tx == null || !tx.isAlive()){
tx = null;
}
try{
switch (propagationLevel) {
case Requires:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level and no txn found, starting a new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level, and existing txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
}
case Mandatory:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level, and no txn is found",
txnConfig.familyName));
}
}
throw new TxnMandatoryException(
format("No txn is found for TxnExecutor '%s' with 'Mandatory' propagation level",
txnConfig.familyName));
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level and txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
case Never:
if (tx != null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level, but txn [%s] is found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
throw new TxnNotAllowedException(
format("No txn is allowed for TxnExecutor '%s' with propagation level 'Never'"+
", but txn '%s' was found",
txnConfig.familyName, tx.getConfig().getFamilyName())
);
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level and no txn is found",
txnConfig.familyName));
}
}
return callable.call(null);
case RequiresNew:
if (tx == null) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagation level and no txn is found, starting new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
GammaTxn suspendedTransaction = tx;
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
try {
return execute(tx, transactionContainer, pool, callable);
} finally {
transactionContainer.txn = suspendedTransaction;
}
}
case Supports:
if(TRACING_ENABLED){
if(tx!=null){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}else{
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
}
return callable.call(tx);
default:
throw new IllegalStateException();
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
}
private <E> E execute(
GammaTxn tx, final TxnThreadLocal.Container transactionContainer, GammaTxnPool pool, final TxnCallable<E> callable)throws Exception{
Error cause = null;
try{
boolean abort = true;
try {
do {
try {
cause = null;
E result = callable.call(tx);
tx.commit();
abort = false;
return result;
} catch (RetryError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a retry",
txnConfig.familyName));
}
}
tx.awaitUpdate();
} catch (SpeculativeConfigurationError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a speculative configuration error",
txnConfig.familyName));
}
}
abort = false;
GammaTxn old = tx;
tx = txnFactory.upgradeAfterSpeculativeFailure(tx,pool);
pool.put(old);
transactionContainer.txn = tx;
} catch (ReadWriteConflict e) {
cause = e;
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a read or write conflict",
txnConfig.familyName));
}
}
backoffPolicy.delayUninterruptible(tx.getAttempt());
}
} while (tx.softReset());
} finally {
if (abort) {
tx.abort();
}
pool.put(tx);
transactionContainer.txn = null;
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Maximum number of %s retries has been reached",
txnConfig.familyName, txnConfig.getMaxRetries()));
}
}
throw new TooManyRetriesException(
format("[%s] Maximum number of %s retries has been reached",
txnConfig.getFamilyName(), txnConfig.getMaxRetries()), cause);
}
@Override
public final int executeChecked(
final TxnIntCallable callable)throws Exception{
try{
return execute(callable);
}catch(InvisibleCheckedException e){
throw e.getCause();
}
}
public int execute(final TxnIntCallable callable){
if(callable == null){
throw new NullPointerException();
}
TxnThreadLocal.Container transactionContainer = getThreadLocalTxnContainer();
GammaTxnPool pool = (GammaTxnPool) transactionContainer.txPool;
if (pool == null) {
pool = new GammaTxnPool();
transactionContainer.txPool = pool;
}
GammaTxn tx = (GammaTxn)transactionContainer.txn;
if(tx == null || !tx.isAlive()){
tx = null;
}
try{
switch (propagationLevel) {
case Requires:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level and no txn found, starting a new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level, and existing txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
}
case Mandatory:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level, and no txn is found",
txnConfig.familyName));
}
}
throw new TxnMandatoryException(
format("No txn is found for TxnExecutor '%s' with 'Mandatory' propagation level",
txnConfig.familyName));
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level and txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
case Never:
if (tx != null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level, but txn [%s] is found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
throw new TxnNotAllowedException(
format("No txn is allowed for TxnExecutor '%s' with propagation level 'Never'"+
", but txn '%s' was found",
txnConfig.familyName, tx.getConfig().getFamilyName())
);
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level and no txn is found",
txnConfig.familyName));
}
}
return callable.call(null);
case RequiresNew:
if (tx == null) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagation level and no txn is found, starting new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
GammaTxn suspendedTransaction = tx;
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
try {
return execute(tx, transactionContainer, pool, callable);
} finally {
transactionContainer.txn = suspendedTransaction;
}
}
case Supports:
if(TRACING_ENABLED){
if(tx!=null){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}else{
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
}
return callable.call(tx);
default:
throw new IllegalStateException();
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
}
private int execute(
GammaTxn tx, final TxnThreadLocal.Container transactionContainer, GammaTxnPool pool, final TxnIntCallable callable)throws Exception{
Error cause = null;
try{
boolean abort = true;
try {
do {
try {
cause = null;
int result = callable.call(tx);
tx.commit();
abort = false;
return result;
} catch (RetryError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a retry",
txnConfig.familyName));
}
}
tx.awaitUpdate();
} catch (SpeculativeConfigurationError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a speculative configuration error",
txnConfig.familyName));
}
}
abort = false;
GammaTxn old = tx;
tx = txnFactory.upgradeAfterSpeculativeFailure(tx,pool);
pool.put(old);
transactionContainer.txn = tx;
} catch (ReadWriteConflict e) {
cause = e;
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a read or write conflict",
txnConfig.familyName));
}
}
backoffPolicy.delayUninterruptible(tx.getAttempt());
}
} while (tx.softReset());
} finally {
if (abort) {
tx.abort();
}
pool.put(tx);
transactionContainer.txn = null;
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Maximum number of %s retries has been reached",
txnConfig.familyName, txnConfig.getMaxRetries()));
}
}
throw new TooManyRetriesException(
format("[%s] Maximum number of %s retries has been reached",
txnConfig.getFamilyName(), txnConfig.getMaxRetries()), cause);
}
@Override
public final long executeChecked(
final TxnLongCallable callable)throws Exception{
try{
return execute(callable);
}catch(InvisibleCheckedException e){
throw e.getCause();
}
}
public long execute(final TxnLongCallable callable){
if(callable == null){
throw new NullPointerException();
}
TxnThreadLocal.Container transactionContainer = getThreadLocalTxnContainer();
GammaTxnPool pool = (GammaTxnPool) transactionContainer.txPool;
if (pool == null) {
pool = new GammaTxnPool();
transactionContainer.txPool = pool;
}
GammaTxn tx = (GammaTxn)transactionContainer.txn;
if(tx == null || !tx.isAlive()){
tx = null;
}
try{
switch (propagationLevel) {
case Requires:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level and no txn found, starting a new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level, and existing txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
}
case Mandatory:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level, and no txn is found",
txnConfig.familyName));
}
}
throw new TxnMandatoryException(
format("No txn is found for TxnExecutor '%s' with 'Mandatory' propagation level",
txnConfig.familyName));
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level and txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
case Never:
if (tx != null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level, but txn [%s] is found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
throw new TxnNotAllowedException(
format("No txn is allowed for TxnExecutor '%s' with propagation level 'Never'"+
", but txn '%s' was found",
txnConfig.familyName, tx.getConfig().getFamilyName())
);
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level and no txn is found",
txnConfig.familyName));
}
}
return callable.call(null);
case RequiresNew:
if (tx == null) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagation level and no txn is found, starting new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
GammaTxn suspendedTransaction = tx;
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
try {
return execute(tx, transactionContainer, pool, callable);
} finally {
transactionContainer.txn = suspendedTransaction;
}
}
case Supports:
if(TRACING_ENABLED){
if(tx!=null){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}else{
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
}
return callable.call(tx);
default:
throw new IllegalStateException();
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
}
private long execute(
GammaTxn tx, final TxnThreadLocal.Container transactionContainer, GammaTxnPool pool, final TxnLongCallable callable)throws Exception{
Error cause = null;
try{
boolean abort = true;
try {
do {
try {
cause = null;
long result = callable.call(tx);
tx.commit();
abort = false;
return result;
} catch (RetryError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a retry",
txnConfig.familyName));
}
}
tx.awaitUpdate();
} catch (SpeculativeConfigurationError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a speculative configuration error",
txnConfig.familyName));
}
}
abort = false;
GammaTxn old = tx;
tx = txnFactory.upgradeAfterSpeculativeFailure(tx,pool);
pool.put(old);
transactionContainer.txn = tx;
} catch (ReadWriteConflict e) {
cause = e;
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a read or write conflict",
txnConfig.familyName));
}
}
backoffPolicy.delayUninterruptible(tx.getAttempt());
}
} while (tx.softReset());
} finally {
if (abort) {
tx.abort();
}
pool.put(tx);
transactionContainer.txn = null;
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Maximum number of %s retries has been reached",
txnConfig.familyName, txnConfig.getMaxRetries()));
}
}
throw new TooManyRetriesException(
format("[%s] Maximum number of %s retries has been reached",
txnConfig.getFamilyName(), txnConfig.getMaxRetries()), cause);
}
@Override
public final double executeChecked(
final TxnDoubleCallable callable)throws Exception{
try{
return execute(callable);
}catch(InvisibleCheckedException e){
throw e.getCause();
}
}
public double execute(final TxnDoubleCallable callable){
if(callable == null){
throw new NullPointerException();
}
TxnThreadLocal.Container transactionContainer = getThreadLocalTxnContainer();
GammaTxnPool pool = (GammaTxnPool) transactionContainer.txPool;
if (pool == null) {
pool = new GammaTxnPool();
transactionContainer.txPool = pool;
}
GammaTxn tx = (GammaTxn)transactionContainer.txn;
if(tx == null || !tx.isAlive()){
tx = null;
}
try{
switch (propagationLevel) {
case Requires:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level and no txn found, starting a new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level, and existing txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
}
case Mandatory:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level, and no txn is found",
txnConfig.familyName));
}
}
throw new TxnMandatoryException(
format("No txn is found for TxnExecutor '%s' with 'Mandatory' propagation level",
txnConfig.familyName));
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level and txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
case Never:
if (tx != null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level, but txn [%s] is found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
throw new TxnNotAllowedException(
format("No txn is allowed for TxnExecutor '%s' with propagation level 'Never'"+
", but txn '%s' was found",
txnConfig.familyName, tx.getConfig().getFamilyName())
);
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level and no txn is found",
txnConfig.familyName));
}
}
return callable.call(null);
case RequiresNew:
if (tx == null) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagation level and no txn is found, starting new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
GammaTxn suspendedTransaction = tx;
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
try {
return execute(tx, transactionContainer, pool, callable);
} finally {
transactionContainer.txn = suspendedTransaction;
}
}
case Supports:
if(TRACING_ENABLED){
if(tx!=null){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}else{
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
}
return callable.call(tx);
default:
throw new IllegalStateException();
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
}
private double execute(
GammaTxn tx, final TxnThreadLocal.Container transactionContainer, GammaTxnPool pool, final TxnDoubleCallable callable)throws Exception{
Error cause = null;
try{
boolean abort = true;
try {
do {
try {
cause = null;
double result = callable.call(tx);
tx.commit();
abort = false;
return result;
} catch (RetryError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a retry",
txnConfig.familyName));
}
}
tx.awaitUpdate();
} catch (SpeculativeConfigurationError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a speculative configuration error",
txnConfig.familyName));
}
}
abort = false;
GammaTxn old = tx;
tx = txnFactory.upgradeAfterSpeculativeFailure(tx,pool);
pool.put(old);
transactionContainer.txn = tx;
} catch (ReadWriteConflict e) {
cause = e;
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a read or write conflict",
txnConfig.familyName));
}
}
backoffPolicy.delayUninterruptible(tx.getAttempt());
}
} while (tx.softReset());
} finally {
if (abort) {
tx.abort();
}
pool.put(tx);
transactionContainer.txn = null;
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Maximum number of %s retries has been reached",
txnConfig.familyName, txnConfig.getMaxRetries()));
}
}
throw new TooManyRetriesException(
format("[%s] Maximum number of %s retries has been reached",
txnConfig.getFamilyName(), txnConfig.getMaxRetries()), cause);
}
@Override
public final boolean executeChecked(
final TxnBooleanCallable callable)throws Exception{
try{
return execute(callable);
}catch(InvisibleCheckedException e){
throw e.getCause();
}
}
public boolean execute(final TxnBooleanCallable callable){
if(callable == null){
throw new NullPointerException();
}
TxnThreadLocal.Container transactionContainer = getThreadLocalTxnContainer();
GammaTxnPool pool = (GammaTxnPool) transactionContainer.txPool;
if (pool == null) {
pool = new GammaTxnPool();
transactionContainer.txPool = pool;
}
GammaTxn tx = (GammaTxn)transactionContainer.txn;
if(tx == null || !tx.isAlive()){
tx = null;
}
try{
switch (propagationLevel) {
case Requires:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level and no txn found, starting a new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level, and existing txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
}
case Mandatory:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level, and no txn is found",
txnConfig.familyName));
}
}
throw new TxnMandatoryException(
format("No txn is found for TxnExecutor '%s' with 'Mandatory' propagation level",
txnConfig.familyName));
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level and txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
return callable.call(tx);
case Never:
if (tx != null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level, but txn [%s] is found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
throw new TxnNotAllowedException(
format("No txn is allowed for TxnExecutor '%s' with propagation level 'Never'"+
", but txn '%s' was found",
txnConfig.familyName, tx.getConfig().getFamilyName())
);
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level and no txn is found",
txnConfig.familyName));
}
}
return callable.call(null);
case RequiresNew:
if (tx == null) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagation level and no txn is found, starting new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
return execute(tx, transactionContainer, pool, callable);
} else {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
GammaTxn suspendedTransaction = tx;
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
try {
return execute(tx, transactionContainer, pool, callable);
} finally {
transactionContainer.txn = suspendedTransaction;
}
}
case Supports:
if(TRACING_ENABLED){
if(tx!=null){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}else{
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
}
return callable.call(tx);
default:
throw new IllegalStateException();
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
}
private boolean execute(
GammaTxn tx, final TxnThreadLocal.Container transactionContainer, GammaTxnPool pool, final TxnBooleanCallable callable)throws Exception{
Error cause = null;
try{
boolean abort = true;
try {
do {
try {
cause = null;
boolean result = callable.call(tx);
tx.commit();
abort = false;
return result;
} catch (RetryError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a retry",
txnConfig.familyName));
}
}
tx.awaitUpdate();
} catch (SpeculativeConfigurationError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a speculative configuration error",
txnConfig.familyName));
}
}
abort = false;
GammaTxn old = tx;
tx = txnFactory.upgradeAfterSpeculativeFailure(tx,pool);
pool.put(old);
transactionContainer.txn = tx;
} catch (ReadWriteConflict e) {
cause = e;
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a read or write conflict",
txnConfig.familyName));
}
}
backoffPolicy.delayUninterruptible(tx.getAttempt());
}
} while (tx.softReset());
} finally {
if (abort) {
tx.abort();
}
pool.put(tx);
transactionContainer.txn = null;
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Maximum number of %s retries has been reached",
txnConfig.familyName, txnConfig.getMaxRetries()));
}
}
throw new TooManyRetriesException(
format("[%s] Maximum number of %s retries has been reached",
txnConfig.getFamilyName(), txnConfig.getMaxRetries()), cause);
}
@Override
public final void executeChecked(
final TxnVoidCallable callable)throws Exception{
try{
execute(callable);
}catch(InvisibleCheckedException e){
throw e.getCause();
}
}
public void execute(final TxnVoidCallable callable){
if(callable == null){
throw new NullPointerException();
}
TxnThreadLocal.Container transactionContainer = getThreadLocalTxnContainer();
GammaTxnPool pool = (GammaTxnPool) transactionContainer.txPool;
if (pool == null) {
pool = new GammaTxnPool();
transactionContainer.txPool = pool;
}
GammaTxn tx = (GammaTxn)transactionContainer.txn;
if(tx == null || !tx.isAlive()){
tx = null;
}
try{
switch (propagationLevel) {
case Requires:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level and no txn found, starting a new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
execute(tx, transactionContainer,pool, callable);
return;
} else {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Requires' propagation level, and existing txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
callable.call(tx);
return;
}
case Mandatory:
if (tx == null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level, and no txn is found",
txnConfig.familyName));
}
}
throw new TxnMandatoryException(
format("No txn is found for TxnExecutor '%s' with 'Mandatory' propagation level",
txnConfig.familyName));
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Mandatory' propagation level and txn [%s] found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
callable.call(tx);
return;
case Never:
if (tx != null) {
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level, but txn [%s] is found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
throw new TxnNotAllowedException(
format("No txn is allowed for TxnExecutor '%s' with propagation level 'Never'"+
", but txn '%s' was found",
txnConfig.familyName, tx.getConfig().getFamilyName())
);
}
if (TRACING_ENABLED) {
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'Never' propagation level and no txn is found",
txnConfig.familyName));
}
}
callable.call(null);
return;
case RequiresNew:
if (tx == null) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagation level and no txn is found, starting new txn",
txnConfig.familyName));
}
}
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
execute(tx, transactionContainer, pool, callable);
return;
} else {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
GammaTxn suspendedTransaction = tx;
tx = txnFactory.newTransaction(pool);
transactionContainer.txn = tx;
try {
execute(tx, transactionContainer, pool, callable);
return;
} finally {
transactionContainer.txn = suspendedTransaction;
}
}
case Supports:
if(TRACING_ENABLED){
if(tx!=null){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}else{
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(
format("[%s] Has 'RequiresNew' propagationLevel and existing txn [%s] was found",
txnConfig.familyName, tx.getConfig().getFamilyName()));
}
}
}
callable.call(tx);
return;
default:
throw new IllegalStateException();
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
}
private void execute(
GammaTxn tx, final TxnThreadLocal.Container transactionContainer, GammaTxnPool pool, final TxnVoidCallable callable)throws Exception{
Error cause = null;
try{
boolean abort = true;
try {
do {
try {
cause = null;
callable.call(tx);
tx.commit();
abort = false;
return;
} catch (RetryError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a retry",
txnConfig.familyName));
}
}
tx.awaitUpdate();
} catch (SpeculativeConfigurationError e) {
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a speculative configuration error",
txnConfig.familyName));
}
}
abort = false;
GammaTxn old = tx;
tx = txnFactory.upgradeAfterSpeculativeFailure(tx,pool);
pool.put(old);
transactionContainer.txn = tx;
} catch (ReadWriteConflict e) {
cause = e;
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Encountered a read or write conflict",
txnConfig.familyName));
}
}
backoffPolicy.delayUninterruptible(tx.getAttempt());
}
} while (tx.softReset());
} finally {
if (abort) {
tx.abort();
}
pool.put(tx);
transactionContainer.txn = null;
}
}catch(RuntimeException e){
throw e;
}catch(Exception e){
throw new InvisibleCheckedException(e);
}
if(TRACING_ENABLED){
if (txnConfig.getTraceLevel().isLoggableFrom(TraceLevel.Coarse)) {
logger.info(format("[%s] Maximum number of %s retries has been reached",
txnConfig.familyName, txnConfig.getMaxRetries()));
}
}
throw new TooManyRetriesException(
format("[%s] Maximum number of %s retries has been reached",
txnConfig.getFamilyName(), txnConfig.getMaxRetries()), cause);
}
}