(未使用AOP)使用ThreadLocal对象把Connection和当前线程绑定, 从而使一个线程中只有一个能控制事务的对象...

每个连接都有自己的独立事务,会造成数据的不一致

这组操作应该要么一起操作成功,要么一起操作失败, 应该使用同一个连接,只有一个能控制事务的对象

需要使用ThreadLocal对象把Connection和当前线程绑定, 从而使一个线程中只有一个能控制事务的对象

 

关于ThreadLocal: Java并发编程:深入剖析ThreadLocal

 

事务控制应该都是在业务层

 

创建一个连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定

/**
 * 连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定
 */
public class ConnectionUtils {

    private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 获取当前线程上的连接
     * @return
     */
    public Connection getThreadConnection() {
        try{
            //1.先从ThreadLocal上获取
            Connection conn = tl.get();
            //2.判断当前线程上是否有连接
            if (conn == null) {
                //3.从数据源中获取一个连接,并且存入ThreadLocal中
                conn = dataSource.getConnection();
                tl.set(conn);
            }
            //4.返回当前线程上的连接
            return conn;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 把连接和线程解绑
     */
    public void removeConnection(){
        tl.remove();//remove()用来移除当前线程中变量的副本
  } 
}

  和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接

 1 /**
 2  * 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接
 3  */
 4 public class TransactionManager {
 5 
 6     private ConnectionUtils connectionUtils;
 7 
 8     public void setConnectionUtils(ConnectionUtils connectionUtils) {
 9         this.connectionUtils = connectionUtils;
10     }
11 
12     /**
13      * 开启事务
14      */
15     public  void beginTransaction(){
16         try {
17             connectionUtils.getThreadConnection().setAutoCommit(false);
18         }catch (Exception e){
19             e.printStackTrace();
20         }
21     }
22 
23     /**
24      * 提交事务
25      */
26     public  void commit(){
27         try {
28             connectionUtils.getThreadConnection().commit();
29         }catch (Exception e){
30             e.printStackTrace();
31         }
32     }
33 
34     /**
35      * 回滚事务
36      */
37     public  void rollback(){
38         try {
39             connectionUtils.getThreadConnection().rollback();
40         }catch (Exception e){
41             e.printStackTrace();
42         }
43     }
44 
45 
46     /**
47      * 释放连接
48      */
49     public  void release(){
50         try {
51             connectionUtils.getThreadConnection().close();//还回连接池中
52             connectionUtils.removeConnection();
53         }catch (Exception e){
54             e.printStackTrace();
55         }
56     }
57 }

 

 1 public class AccountDaoImpl implements IAccountDao {
 2 
 3     private QueryRunner runner;
 4     private ConnectionUtils connectionUtils;
 5 
 6     public void setRunner(QueryRunner runner) {
 7         this.runner = runner;
 8     }
 9 
10     public void setConnectionUtils(ConnectionUtils connectionUtils) {
11         this.connectionUtils = connectionUtils;
12     }
13 
14     public List<Account> findAllAccount() {
15         try{
16             return runner.query(connectionUtils.getThreadConnection(),"select * from account",new BeanListHandler<Account>(Account.class));
17         }catch (Exception e) {
18             throw new RuntimeException(e);
19         }
20     }
21 }

 

转载于:https://www.cnblogs.com/mkl7/p/10688173.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值