(未使用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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM