/*
* This software is distributed under the terms of the FSF
* Gnu Lesser General Public License (see lgpl.txt).
*
* This program is distributed WITHOUT ANY WARRANTY. See the
* GNU General Public License for more details.
*/
package com.scooterframework.transaction;
import com.scooterframework.common.util.CurrentThreadCache;
import com.scooterframework.orm.sqldataexpress.exception.TransactionException;
/**
* ThreadLocalTransactionManager class implements TransactionStarterType,
* TransactionManager and ImplicitTransactionManager interfaces.
*
* @author (Fei) John Chen
*/
public class ThreadLocalTransactionManager
implements TransactionStarterType, TransactionManager, ImplicitTransactionManager
{
private static final String KEY_Transactions = "key.Transactions";
private static final String KEY_TransactionStarterType = "key.TransactionStarterType";
public ThreadLocalTransactionManager() {
}
/**
* Begin a transaction.
*/
public void beginTransaction() {
beginTransaction(null);
}
/**
* Begin a transaction of a specific type.
*/
public void beginTransaction(String type) {
Transaction tx = getTransaction();
if (tx != null && tx.isTransactionStarted()) {
throw new TransactionException("Failed in beginTransaction: transaction already started.");
}
else if (tx == null) {
tx = TransactionFactory.getInstance().createTransaction(type);
setTransaction(tx);
}
if (!tx.isTransactionStarted()) tx.begin();
}
/**
* Commit a transaction.
*/
public void commitTransaction() {
Transaction tx = getTransaction();
if (tx != null) tx.commit();
}
/**
* Rollback a transaction.
*/
public void rollbackTransaction() {
Transaction tx = getTransaction();
if (tx != null) tx.rollback();
}
/**
* Release all resources hold by this transaction.
*/
public void releaseResources() {
Transaction tx = getTransaction();
if (tx != null) {
tx.releaseResources();
tx = null;
setTransaction(tx);
}
}
/**
* Returns a Transaction instance associated with current thread.
*
* @return Transaction
*/
public Transaction getTransaction() {
return (Transaction)CurrentThreadCache.get(KEY_Transactions);
}
/**
* Set a Transaction instance associated with the current thread.
*/
public void setTransaction(Transaction tx) {
CurrentThreadCache.set(KEY_Transactions, tx);
}
/**
* Return true if the transaction is started automatically,
* false if the transaction is started by client calls
* beginTransaciton() or beginTransaciton(type) explicitly.
*
* @return true if auto started transaction, false otherwise.
*/
public boolean isAutoTransaction() {
boolean autoTx = false;
if (TRANSACTION_STARTER_IMPLICIT.equals(getTransactionStarterType())) {
autoTx = true;
}
return autoTx;
}
/**
* Set a type of transaction starter.
*/
public String getTransactionStarterType() {
return (String)CurrentThreadCache.get(KEY_TransactionStarterType);
}
/**
* Set a type of transaction starter.
*/
public void setTransactionStarterType(String type) {
CurrentThreadCache.set(KEY_TransactionStarterType, type);
}
/**
* Begin a transaction implicitly.
*/
public void beginTransactionImplicit() {
if (getTransaction() == null) {
beginTransaction();
setTransactionStarterType(TRANSACTION_STARTER_IMPLICIT);
}
}
/**
* Commit a transaction implicitly.
*/
public void commitTransactionImplicit() {
if (isAutoTransaction()) commitTransaction();
}
/**
* Rollback a transaction implicitly.
*/
public void rollbackTransactionImplicit() {
if (isAutoTransaction()) rollbackTransaction();
}
/**
* Release all resources hold by this transaction implicitly.
*/
public void releaseResourcesImplicit() {
if (isAutoTransaction()) {
setTransactionStarterType(null);
releaseResources();
}
}
}