JdbcUtils

在Dao中处理事务:

public void xxx(){     在dao中应该是对数据库的基本访问,不应该存在业务
	Connection con =null;
	try{
		con=JdbcUtils.getConnection();
		con.setAutoCommitted(false);
		QueryRunner qr=new QueryRunner();
		String sql = ......;
		Object[] params=....;
		qr.update(con,sql,params);
		sql=.....;
		Object[] params=....;
		qr.update(con,sql,params);
		con.commit();
	}catch(Exception e){
		try{
			if(con!=null) con.rollback();
		}catch(Exception e){}
	}finally{
		try{
			con.close();
		}catch(Exception e){}
	}
}

在service中处理业务:

public class xxxService(){  service中不应该出现connection,它只应该在dao中出现
	private xxxDao dao = new xxxDao();
	public void serviceMethod(){
		Connextion con = null;
		try{
			con=JdbcUtils.getConnection();
			con.setAutoCommitted(false);
			dao.daoMethod1(con,....);
			dao.daoMethod2(con,....);
			con.commint();
		}catch(Exception e){
			try{
				if(con!=null) con.rollback();
			}catch(Exception e){}
		}finally{
			try{
				con.close();
			}catch(Exception e){}
		}
	}
}

我们希望可以这样来处理事务

public class xxxService(){
	private XXXDao dao = new XXXDao();
	public void serviceMethod(){
		try{
			JdbcUtils.beginTransaction();  //为con赋值,它不再为null
			dao.daoMethod1(...);				//内部会调用JdbcUtils.getConnection(),如果con不为null,那么返回的是con,多次调用dao方法,返回的是同一个Connection
			dao.daoMethod2(...);
			JdbcUtils.commitTransaction();//调用con.commit()
		}catch(Exception e){
			JdbcUtils.rollbackTransaction();//调用con.rollback()
		}
	}
}

JdbcUtils源码:

 private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
    //事务专用连接
    private static ThreadLocal tl = new ThreadLocal();

    /**
     * 使用连接池返回一个连接对象
     */
    public static Connection getConnection() throws SQLException {
        Connection con = tl.get();
        //当con不等于null,说明已经调用过了beginTransaction()方法了,表示开启了事务
        if(con!=null) return con;
        return dataSource.getConnection();
    }

    /**
     * 返回连接池对象
     */
    public static DataSource getDataSource(){
        return dataSource;
    }
    /**
     *开启事务
     * 1.获取一个connection,设置它的setAutoCommit(false)
     * 2.还要保证dao中使用的连接是我们刚刚创建的!
     * --------
     * 1.创建一个connection,设置为手动提交
     * 2.把这个connection给dao使用
     * 3.还要让commitTransaction或rollbackTransaction可以获取到!
     * @return
     */
    public static void beginTransaction() throws SQLException {
        Connection con = tl.get();
        if(con != null) throw new SQLException("已经开启了事务,就不能重复开启了!");
        //1.给con赋值!
        //2.给con设置为手动提交!
        con = getConnection();
        con.setAutoCommit(false);

        tl.set(con);//把当前线程的连接保存起来
    }

    /**
     * 提交事务
     * 1.获取beginTransaction提供的connection,然后调用commit方法
     */
    public static void commitTransaction() throws SQLException {
        Connection con = tl.get();//获取当前线程的专用连接
        if(con == null) throw new SQLException("没有开启事务,不能提交");
        /*
        1.直接使用con.commit()
         */
        con.commit();
        con.close();
        //把它设置为null,表示事务已经结束了,下次再去调用getConnection返回的就不是con了
        tl.remove();//从tl中移除连接
    }
    /**
     * 提交事务
     * 1.获取beginTransaction提供的connection,然后调用rollback方法
     */
    public static void rollbackTransaction() throws SQLException {
        Connection con = tl.get();
        if(con == null) throw new SQLException("还没有开启事务,不能回滚");
        /*
         1.直接使用con,rollback()
         */
        con.rollback();
        con.close();
        tl.remove();
    }

    /**
     * 释放连接
     * @param connection
     */
    public static void releaseConnection(Connection connection) throws SQLException {
        Connection con = tl.get();
        /**
         * 判断他是不是事务专用,如果是,就不关闭!
         * 如果不是事务专用,那么就关闭
         */
        //如果con == null,说明现在没有事务,那么connection一定不是事务专用的!
        if(con == null) connection.close();
        //如果con != null,说明有实物,那么需判断参数连接是否与con相等,若不等,说明参数连接不是事务专用连接
        if(con != connection) connection.close();
    }

你可能感兴趣的:(JdbcUtils)