• 进行事务操作通过连接池拿对象的第三次修改


    package tools;


    import java.sql.Connection;
    import java.sql.SQLException;


    import javax.sql.DataSource;


    import com.mchange.v2.c3p0.ComboPooledDataSource;


    public class JdbcUtils {
    private static ThreadLocal<Connection> tl=new ThreadLocal<Connection>();//每一个线程进来都是不同的connection事务对象,防止多线程的带来的问题
    //使用文件的默认配置得到一个连接池对象
    private static ComboPooledDataSource dataSource=new ComboPooledDataSource();
    //返回一个连接对象
    public static Connection getConnection()throws SQLException{
    Connection con=tl.get();//从当前线程中拿到对应的connection事务对象
    if(con!=null){//判断该事物对象是否为空
    return con;//不为空的话会返回当前的事务对象
    }
    return dataSource.getConnection();//为空的话就返回一个新的连接对象
    }
    //得到连接池的对象
    public static DataSource getDataSource(){
    return dataSource;
    }

    //开启事务
    //获得一个connection对象,设置它的setAutoCommit(false)
    //保证dao中的连接是我们刚刚创建的
    //创建一个connection,设置为手动提交
    //把这个connection给dao
    //rooback和commit都可以得到


    public static void beginTransaction() throws SQLException{
    Connection con=tl.get();//获取自己的connection
    if(con!=null){//避免因为开了很多次而出现事务的connection不是同一个的情况
    throw new RuntimeException("兄弟开一次就好了嘛,紧到开,你是吃霉了啊!");
    }
    con=getConnection();//为事务con进行赋值
    con.setAutoCommit(false);//事务的开始
    tl.set(con);//把当前的线程保存起来,其他的方法使用的话也可以使用
    }
    //提交事务
    //获得beginTransaction提供的connection对象,然后调用commit方法
    public static void commitTransaction() throws SQLException{
    Connection con=tl.get();//获取自己的connection
    if(con==null) throw new RuntimeException("还没开启,你就提交,你在™逗我");//避免出现因为还未出现实务connection对象的情况的出现
    con.commit();
    con.close();
    tl.remove();//将当前线程中的事物connection移除掉
    }
    //提交事务
    //获得beginTransaction提供的connection对象,然后调用rollback方法
    public static void rollbackTransaction() throws SQLException{
    Connection con=tl.get();//获取自己的connection
    if(con==null) throw new RuntimeException("还没开启,你就回滚,你在™逗我");//避免出现因为还未出现事务connection对象的情况的出现
    con.rollback();
    con.close();
    tl.remove();//将当前线程中的事物connection移除掉
    }
    //释放连接
    //判断是否为实物专用
    //如果不是实物专用就关闭
    public static void releaaseConnection(Connection connection) throws SQLException{
    Connection con=tl.get();//获取自己的connection
    //如果con为空的情况下connection就不是事务专用的连接
    if(con==null) connection.close();
    //如果con和connection不是同于一个说明不是一个实务连接
    if(con!=connection)connection.close();
    }

    }







    package tools;


    import java.sql.Connection;
    import java.sql.SQLException;


    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.ResultSetHandler;


    public class TxQueryRunner extends QueryRunner {


    @Override
    public int[] batch(String sql, Object[][] params) throws SQLException {
    //1.得到连接
    //2.执行父类的方法 传递连接对象
    //3。释放连接
    //4.返回值
    Connection con=JdbcUtils.getConnection();//得到链接的对象有可能不是事物的对象,但前面已经赋值,这里的con应该是连接对象
    int[] result=super.batch(con,sql, params);
    JdbcUtils.releaaseConnection(con);
    return result;
    }
    @Override
    public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params){
    Connection con=null;
    try {
    con = JdbcUtils.getConnection();//得到链接的对象有可能不是事物的对象,但前面已经赋值,这里的con应该是连接对象
    } catch (SQLException e2) {
    e2.printStackTrace();
    }
    T result=null;
    try {
    result = super.query(con,sql,rsh, params);
    } catch (SQLException e1) {
    e1.printStackTrace();
    }
    try {
    JdbcUtils.releaaseConnection(con);
    } catch (SQLException e) {
    e.printStackTrace();
    }
    return result;
    }


    @Override
    public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {
    Connection con=JdbcUtils.getConnection();//得到链接的对象有可能不是事物的对象,但前面已经赋值,这里的con应该是连接对象
    T result=super.query(con,sql, rsh);
    JdbcUtils.releaaseConnection(con);
    return result;
    }


    @Override
    public int update(String sql) throws SQLException {
    Connection con=JdbcUtils.getConnection();//得到链接的对象有可能不是事物的对象,但前面已经赋值,这里的con应该是连接对象
    int result=super.update(con,sql);
    JdbcUtils.releaaseConnection(con);
    return result;
    }


    @Override
    public int update(String sql, Object param) throws SQLException {
    Connection con=JdbcUtils.getConnection();//得到链接的对象有可能不是事物的对象,但前面已经赋值,这里的con应该是连接对象
    int result=super.update(con,sql, param);
    JdbcUtils.releaaseConnection(con);
    return result;
    }


    @Override
    public int update(String sql, Object... params) throws SQLException {
    Connection con=JdbcUtils.getConnection();//得到链接的对象有可能不是事物的对象,但前面已经赋值,这里的con应该是连接对象
    int result=super.update(con,sql, params);
    JdbcUtils.releaaseConnection(con);
    return result;
    }


    }





    package demo1;


    import java.sql.SQLException;
    import org.junit.Test;
    import tools.AccountDao;
    import tools.JdbcUtils;


    public class demo {


    AccountDao dao =new AccountDao();//获得account对象
    @Test
    public void demo() throws SQLException{

    try{
    JdbcUtils.beginTransaction();//开启了事务connection
    dao.update("ls", 100);//对数据库的操作
    // if(true) throw new RuntimeException("我挂掉了,救救我吧啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!!!!!");//测试当抛出异常的时候能不能回滚回去
    dao.update("ls", -100);
    JdbcUtils.commitTransaction();//关闭链接  直接抛异常没有处理
    }catch (Exception e) {
    JdbcUtils.rollbackTransaction();
    }


    }
    }





    package tools;
    import java.sql.SQLException;


    public class AccountDao {
    public static void update(String name, double money) throws SQLException {
    TxQueryRunner qr = new TxQueryRunner();
    String sql = "update account set balance=balance+? where name=?";
    Object[] params = { money, name };
    //写入参数
    qr.update(sql,params);
    //在TxQueryRunner中含有获得连接的方法,所有没有必要在传入一个连接的对象
    }
    }

  • 相关阅读:
    HashMap
    java反射
    arraylist和linkedlist区别
    int和Integer的区别
    java 数组排序并去重
    矩阵链乘法问题
    找零问题
    硬币收集问题
    最大借书量问题
    钢条切割问题
  • 原文地址:https://www.cnblogs.com/csnd/p/16675746.html
Copyright © 2020-2023  润新知