/* * 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 java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import com.scooterframework.orm.sqldataexpress.config.DatabaseConfig; import com.scooterframework.orm.sqldataexpress.connection.DatabaseConnectionContext; import com.scooterframework.orm.sqldataexpress.connection.UserDatabaseConnection; import com.scooterframework.orm.sqldataexpress.connection.UserDatabaseConnectionFactory; import com.scooterframework.orm.sqldataexpress.exception.TransactionException; import com.scooterframework.orm.sqldataexpress.util.DAOUtil; /** * AbstractTransactionImpl class has common methods. * * @author (Fei) John Chen */ abstract public class AbstractTransactionImpl implements Transaction { /** * Initialize JdbcTransaction */ public AbstractTransactionImpl() { //Note: Do not initiate a default connection here as a request may // need its own special connection. Only initialize a connection // at request time. } /** * Return transaction type */ public String getTransactionType() { return transactionType; } /** * Release all resources managed by this transaction. */ public void releaseResources() { if (bAllResourcesReleased) return; bTransactionHasEnded = true; try { Iterator<UserDatabaseConnection> it = connList.iterator(); while(it.hasNext()) { UserDatabaseConnection udc = it.next(); DAOUtil.closeConnection(udc.getConnection()); } connList.clear(); nameConnMap.clear(); bAllResourcesReleased = true; } catch(Exception ex) { throw new TransactionException("eroror in releaseResources()", ex); } } /** * Start a transaction. */ public void begin() { bTransactionHasStarted = true; } /** * Commit a transaction. */ public void commit() { if (bTransactionHasCommitted) { throw new TransactionException("Transaciton has already been committed."); } else { bTransactionHasCommitted = true; } } /** * Rollback a transaction. */ public void rollback() { if (bTransactionHasRollbacked) { throw new TransactionException("Transaciton has already been rollbacked."); } else { bTransactionHasRollbacked = true; } } /** * Check if transaction has started. */ public boolean isTransactionStarted() { return bTransactionHasStarted; } /** * Check if transaction has ended. */ public boolean isTransactionEnded() { return bTransactionHasEnded; } /** * Check if all resources have been released. */ public boolean isAllResourcesReleased() { return bAllResourcesReleased; } /** * Return a connection to the database * * @return UserDatabaseConnection */ public UserDatabaseConnection getConnection() { String connectionName = DatabaseConfig.getInstance().getDefaultDatabaseConnectionName(); return getConnection(connectionName); } /** * Return a connection to the database * * @param connectionName name of a connection * @return UserDatabaseConnection */ public UserDatabaseConnection getConnection(String connectionName) { UserDatabaseConnection udc = getCachedUserDatabaseConnection(connectionName); //create a new UserDatabaseConnection if (udc == null) { udc = UserDatabaseConnectionFactory.getInstance().createUserDatabaseConnection(connectionName); registerResource(udc.getConnectionName(), udc); } return udc; } /** * Return a connection based on connection context * * @param dcc a DatabaseConnectionContext instance * @return UserDatabaseConnection */ public UserDatabaseConnection getConnection(DatabaseConnectionContext dcc) { if (dcc == null) throw new IllegalArgumentException("Input DatabaseConnectionContext instance is null."); String connectionName = dcc.getConnectionName(); UserDatabaseConnection udc = getCachedUserDatabaseConnection(connectionName); //create a new UserDatabaseConnection if (udc == null) { udc = UserDatabaseConnectionFactory.getInstance().createUserDatabaseConnection(dcc); registerResource(connectionName, udc); } return udc; } private UserDatabaseConnection getCachedUserDatabaseConnection(String name) { return (UserDatabaseConnection)nameConnMap.get(name); } /** * Register a resource which is to be managed by this transaction. */ private void registerResource(String name, UserDatabaseConnection resource) { if (nameConnMap.containsKey(name)) return; nameConnMap.putIfAbsent(name, resource); connList.add(resource); } protected ConcurrentHashMap<String, UserDatabaseConnection> nameConnMap = new ConcurrentHashMap<String, UserDatabaseConnection>(); protected List<UserDatabaseConnection> connList = new ArrayList<UserDatabaseConnection>(); protected String transactionType = null; protected boolean bTransactionHasStarted = false; protected boolean bTransactionHasEnded = false; protected boolean bTransactionHasCommitted = false; protected boolean bTransactionHasRollbacked = false; protected boolean bAllResourcesReleased = false; }