通常我们会把事务处理放在业务层。
[1]引子
比如:
业务逻辑方法
public A bussinessMethod(){
DaoA a = new DaoA();
a.udpate();
DaoB b = new DaoB();
b.update;
}
假设,上面的事务是自动提交的。
那么,我们就可以什么不考虑。但是有一个问题,创建DAO对象的时候两个对象用的是不同的Connection对象。
再假定我们的取得连接的代码是
public Connection getConnection(String username, String password)
throws SQLException {
Connection con = DriverManager
.getConnection(conStr, username, password);
return con;
}
这个方法的一个调用。
那么如果,我们需要自己控制事务的开始和结束。
如何控制呢。
也许又有了新的方法
public A bussinessMethod(){
DaoA a = new DaoA();
a.beginTx();
a.udpate();
a.endTx();
a.close();
DaoB b = new DaoB();
b.beginTx();
b.update;
b.endTx();
b.close();
}
这样我们就控制了事务,并且我们也只有这样才能实现,因为,不同的DAO取得的是不同的Connection对象。
[2]问题
那么怎么才能实现两个或多个DAO用同一个事务来控制呢?
首先就要解决一个根本问题,我们在一个事务中,不同的DAO取得的是同一个Connection,这个要怎么实现呢。我们想到了TheadLocal.
[3]方案
因为当一个业务逻辑要对多个DAO进行处理的时候,此操作属于同一个线程内。所以,我们希望能把此Connection放在线程内,或者和线程有关联。
第一个方案,可以用Map来使现。
就是Map<Thread,Connection>
但是这个map维护起来比较麻烦,如果一直put的话,那么这个map随着系统的运行就会越来越大。
第二个方案,就是用ThreadLocal
在任何一个线程内都可以用ThreadLocal来保存一个变量的copy,这样,如果此对象存在,就可以直接取用。
如果把Connection存在ThreadLocal也一样。
所以,在同一个线程内,就可以保证取得到的是同一个Connection.
[4]实现
代码
private static ThreadLocal<Connection> localCon = new ThreadLocal<Connection>();
public final static Connection getConnection() throws SQLException {
Connection con = localCon.get();
if(con==null||con.isClosed()){
con = new OracleJdbcDatasource().getConnection();
localCon.set(con);
}
return con;
}
这样就实现了上面的问题。
[5]新的事务管理
public A bussinessMethod(){
DaoA a = new DaoA();
DaoB b = new DaoB();
a.beginTx();
a.udpate();
b.beginTx();
b.update;
a.endTx();
a.close();
// b.endTx();
// b.close();
能实现一样的效果
}
上面的黑体部分,就可以实现对事务的统一管理。
[6]改进
上面的方法给人的感觉有点别扭,但是却能实现事务的统一管理。
我还要继续改进。
|----------------------------------------------------------------------------------------|
版权声明 版权所有 @zhyiwww
引用请注明来源 http://www.blogjava.net/zhyiwww
|----------------------------------------------------------------------------------------|
posted on 2010-02-11 15:34
zhyiwww 阅读(1864)
评论(2) 编辑 收藏 所属分类:
j2ee