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

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

  • 相关阅读:
    leetcode-hard-array-239. Sliding Window Maximum
    leetcode-hard-array- 227. Basic Calculator II
    leetcode-hard-array-287. Find the Duplicate Number
    leetcode-hard-array-128. Longest Consecutive Sequence
    leetcode-hard-array-41. First Missing Positive-NO
    基于深度学习的自然图像和医学图像分割:损失函数设计(1)
    对于自己,2020年应该思考的问题和要完成的任务
    查看两张相似图形的差异
    几种模型评价指标实现代码
    实验二涉及的步骤记录
  • 原文地址:https://www.cnblogs.com/highriver/p/2129594.html
Copyright © 2020-2023  润新知