zhyiwww
用平实的笔,记录编程路上的点点滴滴………
posts - 536,comments - 394,trackbacks - 0
通常我们会把事务处理放在业务层。

[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 阅读(1853) 评论(2)  编辑  收藏 所属分类: j2ee

FeedBack:
# re: 事务管理与ThreadLocal
2010-02-11 17:07 | Evan Wu
两个方法使用同一个事务,最好还是把它们合二为一。
ps: Hibernate中的Connection就是用的ThreadLocal  回复  更多评论
  
# re: 事务管理与ThreadLocal
2010-02-12 10:02 | zhyiwww
曾经,我也用hibernate的sessionFactory创建session,却不知道为什么要用threadlocal,现在我明白了  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: