I have such things as:
1) DAO class with methods, used to perform transaction, such as withdrawSum(int idAccount, float amount) and putSum(int idAccount, float amount) which use java.sql.Connection and java.sql.PreparedStatement classes to perform atomic operations with DB.
2) java.lang.reflect.InvocationHandler implementor, whick is used to get connection before transaction and commit/rollback after transaction:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Connection connection = null;
try{
connection = DaoUtil.INSTANCE.getConnection();
connection.setAutoCommit(false);
method.invoke(connection, args);
connection.commit();
} catch(InvocationTargetException ex){
connection.rollback();
} finally{
DaoUtil.INSTANCE.closeConnection(connection);
}
return null;
}
3) Transaction manager, which creates Proxy instance and with its help calls method which executes transaction, something like this:
TransactionManager transManager = new TransactionManager();
InvocationHandler transHandler = new MyInvocationHandler(transManager);
TransactionManager proxy = (TransactionManager) Proxy.newProxyInstance(
transManager.getClass().getClassLoader(), transManager.getClass().getInterfaces(), transHandler);
proxy.transferMoney(withdrawAccountid, putAccountId, transactionSum);
…..
public void transferMoney(int withdrawAccountid, int putAccountId, float transactionSum){
AccountDao.getInstance().withdrawSum(withdrawAccountid, transactionSum);
AccountDao.getInstance().putSum(putAccountId, transactionSum);
}
The question is: to execute statement in DAO methods, I need initialized Connection object. It is intialized and passed to the invoke-method of the InvocationHandler. How it should be correctly initialized in DAO-methods? Any ideas? Thanks in advance.
Since transactions are naturally associated with threads, a typical approach here is to store
Connectionin aThreadLocalstorage during the scope of transaction.Then you can make these connections available to DAOs using different approaches:
DAOs can obtain
Connections by calling some static methodA custom
DataSourcecan be injected into DAOs – itsgetConnection()method would return the connection associated with current transaction, note that connection should be proxied in order to ignoreclose(). This approach doesn’t couple your DAOs with transaction management code.Also note that all these things are already implemented by some libraries, for example, by Spring Framework. Perhaps you can leverage it instead of creating your own solution, or at least take a look at their design (in Spring, different approaches for obtaining connections are implemented by
DataSourceUtilsandTransactionAwareDataSourceProxy, respectively).See also: