ThreadLocal与事务

ThreadLocal中放置connection, 保证事务中的DAO类获取的都是同一个connection,这样才保证事务。

下面是网上找到的一个具体的例子http://www.pin5i.com/showtopic-26854.html

-----------------------------------------------------------------------------------

通常我们会把事务处理放在业务层。

[1]引子

比如:
业务逻辑方法

  1. public A bussinessMethod(){
  2.   DaoA  a = new DaoA();
  3.   a.udpate();
  4.   DaoB  b = new DaoB();
  5.   b.update;
  6. }
复制代码

假设,上面的事务是自动提交的。

那么,我们就可以什么不考虑。但是有一个问题,创建DAO对象的时候两个对象用的是不同的Connection对象。

再假定我们的取得连接的代码是

  1.     public Connection getConnection(String username, String password)
  2.             throws SQLException {
  3.         Connection con = DriverManager
  4.                 .getConnection(conStr, username, password);
  5.         return con;
  6.     }
复制代码

这个方法的一个调用。

那么如果,我们需要自己控制事务的开始和结束。

如何控制呢。

也许又有了新的方法

  1. public A bussinessMethod(){
  2.   DaoA  a = new DaoA();
  3.   a.beginTx();
  4.   a.udpate();
  5.   a.endTx();
  6.   a.close();
  7.   DaoB  b = new DaoB();
  8.   b.beginTx();
  9.   b.update;
  10.   b.endTx();
  11.   b.close();
  12. }
复制代码

这样我们就控制了事务,并且我们也只有这样才能实现,因为,不同的DAO取得的是不同的Connection对象。

[2]问题

那么怎么才能实现两个或多个DAO用同一个事务来控制呢?

首先就要解决一个根本问题,我们在一个事务中,不同的DAO取得的是同一个Connection,这个要怎么实现呢。我们想到了TheadLocal.

[3]方案

因为当一个业务逻辑要对多个DAO进行处理的时候,此操作属于同一个线程内。所以,我们希望能把此Connection放在线程内,或者和线程有关联。

第一个方案,可以用Map来使现。

就是Map<Thread,Connection>

但是这个map维护起来比较麻烦,如果一直put的话,那么这个map随着系统的运行就会越来越大。

第二个方案,就是用ThreadLocal

在任何一个线程内都可以用ThreadLocal来保存一个变量的copy,这样,如果此对象存在,就可以直接取用。

如果把Connection存在ThreadLocal也一样。

所以,在同一个线程内,就可以保证取得到的是同一个Connection.

[4]实现

  1.     private static ThreadLocal<Connection> localCon = new ThreadLocal<Connection>();
  2.     public final static Connection getConnection() throws SQLException {
  3.      
  4.         Connection con = localCon.get();
  5.      
  6.         if(con==null||con.isClosed()){
  7.             con = new OracleJdbcDatasource().getConnection();
  8.          
  9.             localCon.set(con);
  10.         }
  11.      
  12.         return con;
  13.     }
复制代码

这样就实现了上面的问题。

[5]新的事务管理

  1. public A bussinessMethod(){
  2.   DaoA  a = new DaoA();
  3.   DaoB  b = new DaoB();
  4.   a.beginTx();
  5.   a.udpate();
  6.   b.beginTx();
  7.   b.update;
  8.   a.endTx();
  9.   a.close();
  10. //  b.endTx();
  11. //  b.close();
  12. 能实现一样的效果
  13.  
  14. }
复制代码

上面的黑体部分,就可以实现对事务的统一管理。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值