我有这样的事情:
1) DAO类,带有用于执行事务的方法,例如withdrawSum(int idAccount, float amount)
和putSum(int idAccount, float amount)
,它们使用java.sql.Connection和java.sql.PreparedStatement类来执行原子操作与DB。
2)java.lang.reflect。 InvocationHandler 实现者,whick用于在事务之前获取连接并在事务之后提交/回滚:
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)事务管理器,它创建代理实例并使用其执行事务的帮助调用方法,如下所示:
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);
}
问题是:要在DAO方法中执行语句,我需要初始化连接对象。它是初始化的并传递给InvocationHandler的 invoke - 方法。如何在DAO方法中正确初始化?有任何想法吗?提前谢谢。
答案 0 :(得分:1)
由于事务自然地与线程相关联,因此这里的典型方法是在事务范围内将Connection
存储在ThreadLocal
存储中。
然后,您可以使用不同的方法将这些连接提供给DAO:
DAO可以通过调用一些静态方法
Connection
可以将自定义DataSource
注入到DAO中 - 其getConnection()
方法将返回与当前事务关联的连接,请注意应该代理连接以忽略close()
。此方法不会将DAO与事务管理代码耦合。
另请注意,所有这些内容都已由某些库实现,例如,Spring Framework。也许您可以利用它而不是创建自己的解决方案,或者至少看看他们的设计(在Spring中,分别通过DataSourceUtils
和TransactionAwareDataSourceProxy
实现了获取连接的不同方法。)
另见: