博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ThreadLocal与事务
阅读量:5298 次
发布时间:2019-06-14

本文共 1909 字,大约阅读时间需要 6 分钟。

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. }
复制代码

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

转载于:https://www.cnblogs.com/highriver/archive/2011/08/06/2129594.html

你可能感兴趣的文章
lua语言入门之Sublime Text设置lua的Build System
查看>>
解决win8使用内置管理员不能打开应用商城、天气等问题
查看>>
vue.js基础
查看>>
电脑的自带图标的显示
查看>>
globalization与全球化
查看>>
[转载] redis 的两种持久化方式及原理
查看>>
关于在Idea 创建Maven项目时,无法在source文件下创建servlet文件问题解决!
查看>>
对 HTTP 304 的理解
查看>>
深入理解css中的margin属性
查看>>
C++ 删除字符串的两种实现方式
查看>>
电容选型
查看>>
ORA-01502: 索引'P_ABCD.PK_WEB_BASE'或这类索引的分区处于不可用状态
查看>>
Spring EL hello world实例
查看>>
百度地图API地理位置和坐标转换
查看>>
MyBatis学习总结(六)——调用存储过程
查看>>
code-代码平台服务器路径
查看>>
离线安装 Visual Studio Express 而不下载整个镜像文件的方法(转载)
查看>>
2017-2018-2偏微分方程复习题解析10
查看>>
Java抽象类和接口的比较
查看>>
web技术工具帖
查看>>