dbutils事务管理---ThreadLocal(Connection)

  在日常的项目开发中,我们知道有时候一些业务业务逻辑操作,必须在一块执行,要么全部执行成功,要么全部执行失败,这就要求我们在程序代码中对需要执行的sqlyu语句加上事务来执行、管理。

  在dbutils工具中,对事务管理主要用到了ThreadLocal<T>这个容器(类似于容器),将开启事务的连接绑定到当前线程上去。

原理:将开启事务的链接保存到当前线程上,开启事务,在下面调用的Dao都是从当前线程获得的链接都是已经开启过事务的连接,最后在提交事务,关闭连接即可

实现代码如下:

1.JDBCUtil_c3p0.java

package com.nyist.dbutils.Utils;

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCUtil_c3p0 {
    
    private static ThreadLocal<Connection> t1 =  new ThreadLocal<Connection>();        //定义一个ThreadLocal 来保存绑定再当前线程上的链接
    private static ComboPooledDataSource cs = null;        
    static{
        cs = new ComboPooledDataSource();
    }
    public static DataSource getDataSource(){
        return cs;
    } 
    
    public static Connection getConnection() throws SQLException{
        try {
            //得到当前线程上绑定的链接开启事务
            Connection conn = t1.get();
            if(conn==null){
                conn = cs.getConnection();                //从数据库连接池里得到一个链接
                t1.set(conn);                            //将得到的连接绑定到当前线程上
            }
            return conn;                                //返回该连接
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
    
    
    //开启事务
    public static void startTransaction(){
        try {
            //得到当前线程上绑定的链接开启事务
            Connection conn = t1.get();            
            if(conn==null){
                conn = getConnection();
                t1.set(conn);
            }
            conn.setAutoCommit(false);            //开启事务
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
    
    
    //提交事务
    public static void commitTransaction(){
        try{
            Connection conn = t1.get();                //得到当前线程上绑定的连接
            if(conn != null){                        //如果得到的连接不为空
                conn.commit();                        //提交事务
            }
        }catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }
    
    //关闭数据库连接   从map容器中删除掉关闭掉的连接
    public static void closeConnection() throws SQLException{
        try{
            Connection conn = t1.get();                //得到当前线程上绑定的连接
            if(conn != null){                        //如果得到的连接不为空
                conn.close();                        //关闭事务
            }
        }finally{
            t1.remove();                            //**重点,千万要牢记** 解除当前线程上的绑定--从threadLocal中移除关闭的链接
            //如果不将关闭的连接从ThreadLocal容器中移除,ThreadLocal容器越老越大,最终会将内存耗尽
        }
    }
}    
 

2.BusinessService.java

package com.nyist.dbutils.service;
import java.sql.Connection;
import java.sql.SQLException;
import org.junit.Test;
import com.nyist.dbutils.Utils.JDBCUtil_c3p0;
import com.nyist.dbutils.dao.AccountDao;
import com.nyist.dbutils.model.Account;

public class BussinessSercice {
    
    @Test
    public void test1() throws SQLException{
        transfer2(2, 1, 200);
    }
    
    
    public void transfer1(int sourceid,int targerid,double money) throws SQLException{
        Connection conn = null;
        try{
            conn = JDBCUtil_c3p0.getConnection();                //拿到数据库链接
            conn.setAutoCommit(false);                                 //开启事务管理
            
            AccountDao dao = new AccountDao(conn);
            Account saccount =dao.find(sourceid);
            Account taccount =dao.find(targerid);
            saccount.setMoney(saccount.getMoney()-money);
            taccount.setMoney(taccount.getMoney()+money);
            dao.update(taccount);
            dao.update(saccount);
            conn.commit();
        }finally{
            if(conn != null)
                conn.close();
        }
    }
    
    //用上ThreadLoca2
    public void transfer2(int sourceid,int targerid,double money) throws SQLException{
        try{
            //1.上来先开启事务
            JDBCUtil_c3p0.startTransaction();
            //2.调用Dao
            AccountDao dao = new AccountDao();
            Account saccount =dao.find(sourceid);
            Account taccount =dao.find(targerid);
            saccount.setMoney(saccount.getMoney()-money);
            taccount.setMoney(taccount.getMoney()+money);
            dao.update(taccount);
            dao.update(saccount);
            //3.提交事务
            JDBCUtil_c3p0.commitTransaction();
        }finally{
            //4.关闭连接
            JDBCUtil_c3p0.closeConnection();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lvhaoguang0/article/details/81098586