JDBC对事务进行管理

版权声明:本博主所有播客均为原创作品,如有商业用途,抄袭等,必追究其法律程序。 https://blog.csdn.net/wangzijian121/article/details/91411004

首先这个是我自己在学习中总结出来的,也就是自己的理解,仅限交流学习,不足之处请各位指正。

在最开始学习JDBCUtils是,将数据库事务的处理直接放在到dao层实现,这样看起来很简单,但是在MVC分层思想下,但是dao层只负责与数据库的数据交互(CRUD),Service层中要想处理事务,还必须获取Connection连接,这就暴露了Connection连接。

解决的办法可以参照我画的这个图:首先将Connection隐藏,把它隐藏在JDBCUtils中,并将Transaction放到JDBCutils处理,因此在JDBCutils中就会有2个Connection,一个是未开启事务时的Connection ,一个是事务专用的TConnection,这样既满足dao中不处理事务,又满足Service层中隐藏Connection。
最后发现:虽然解决了是事务的 处理,但是每次执行都必须重新getConnection()、releaseConnection()方法,因此直接重写QueryRunner类中的Update()、Query() 方法,将对连接的操作,放到TxQueryRunner中执行,dao中直接实例化TxQueryRunner即可。
在这里插入图片描述

jdbcUtils.java

package JDBC_tools;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class jdbcUtils {

    public static ComboPooledDataSource ds=new ComboPooledDataSource(  );
    //表示他是事务的专用连接
    private  static Connection conn =null;

    /**
     * 使用连接池返回一个连接对象
     * 使用的是文件的默认配置,使用时必须给出c3p0-config.xml
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {

        if(conn!=null) return conn;
        return ds.getConnection();
    }
    /**
     * 返回连接池对象
     * @return
     */
    public static DataSource getDataSource(){
        return ds;
    }
    /**
     * 开启事务
     * 必须保证dao commit rollback中的连接是使用同一个连接
     */
   public static void beginTransaction(){
       try {
           //获取连接
            conn=getConnection();
           //设置自动提交为false
           conn.setAutoCommit( false );

       } catch (SQLException e) {
           e.printStackTrace();
       }
   }
    /**
     * 提交事务
     */
   public static void commitTransaction(){
       try {
           if(conn==null){

               throw new SQLException("还没开启事务!");
           }
           conn.commit();
           conn.close();
           conn=null;
       } catch (SQLException e) {
           e.printStackTrace();
       }
   }
    /**
     * 回滚事务
     */
   public  static void rollbacktranaction(){
       try {
           if(conn==null){

               throw new SQLException("还没开启事务!");
           }
           conn.rollback();
           conn.close();
           conn=null;
       } catch (SQLException e) {
           e.printStackTrace();
       }
   }

/**
 * 释放连接
 */
public  static void releaseConnection(Connection connection) throws SQLException {
    //判断是否为事务专用连接
    //如果是事务专用连接就不做处理(等待用完后commit处理)
    //如果不是事务专用连接,那么就要关闭

    //如果conn为空,那么它一定不是事务连接,直接关闭了!
    if(conn==null) connection.close();

    //将要关闭的连接与事务专用连接对比,如果不一样就直接关闭
    if(conn!=connection){
        connection.close();
    }
}
}

Dao.java

package JDBC_tools;

import org.apache.commons.dbutils.QueryRunner;

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

public class dao {

    private static void update() throws SQLException {

        QueryRunner qr=new TxQueryRunner();
        String sql="update person set money=9999 where id=1";
        //这里的连接必须是我自己定义的连接,不能使用数据库连接池的连接,
        //必须保证多次调用的Connection是同一个连接
        qr.update( sql );

    }

    public static void main(String[] args) throws SQLException {

        update( );
    }
}

TxQueryRunner.java

package JDBC_tools;

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

import java.sql.*;

public class TxQueryRunner extends QueryRunner {


    @Override
    public int[] batch(String sql, Object[][] params) throws SQLException {
        Connection conn=jdbcUtils.getConnection();
        int [] result=super.batch(conn,sql,params);
        jdbcUtils.releaseConnection( conn );
        return result;
    }

    @Override
    public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
        Connection conn=jdbcUtils.getConnection();
        T result= super.query(conn, sql, rsh, params );
        jdbcUtils.releaseConnection( conn );
        return result;

    }

    @Override
    public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {
        Connection conn=jdbcUtils.getConnection();
        T result= super.query(conn, sql, rsh );
        jdbcUtils.releaseConnection( conn );
        return result;
    }
    @Override
    public int update(String sql) throws SQLException {
        Connection conn=jdbcUtils.getConnection();
        int  result= super.update(conn,sql);
        jdbcUtils.releaseConnection( conn );
        return result;

    }

    @Override
    public int update(String sql, Object param) throws SQLException {
        Connection conn=jdbcUtils.getConnection();
        int  result= super.update(conn,sql,param);
        jdbcUtils.releaseConnection( conn );
        return result;
    }

    @Override
    public int update(String sql, Object... params) throws SQLException {
        Connection conn=jdbcUtils.getConnection();
        int  result= super.update(conn,sql,params);
        jdbcUtils.releaseConnection( conn );
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/wangzijian121/article/details/91411004