QueryRunner可以实现事务操作,但是在构造器中不能传入DataSource连接池,如果将链接吃传入连接池对象的话,QueryRunner执行完SQL语句就会自动关闭connection对象,无法实现手动提交事务。
手动提交事务的关键
所有SQL语句的执行 要使用同一个链接 同一个connection
1.在获取连接后第一步先把事务的自动提交关闭 用链接调用setAutoCommit(false) 传入false。
2.在确认所有SQL语句都执行完毕后,手动提交事务,链接调用commit()方法。
3.如果因为某种原因没有执行完SQL语句,就会出现异常,进入到catch中,此时要保证能捕捉到任何形式的异常信息,所以就抓最大号的异常Exception。捕捉到异常后,进行事务的回滚,connection调用rollback()方法;
@Test
/**
* 需求不变,采用DbUtils来实现数据表操作
* 事务操作,和SQL语句执行的连接对象,不是一个
*/
public void testTransfer(){
//连接对象
Connection con = null;
try {
con = DruidUtils.getConnection();
//开启事务
con.setAutoCommit(false);
//创建QueryRunner对象,不要传递连接池对象
QueryRunner qr = new QueryRunner();
String sql1 = "update account set money = money - ? where name = ?";
String sql2 = "update account set money = money + ? where name = ?";
//执行SQL,手动传递连接
int i = qr.update(con,sql1, 1000, "tom");
System.out.println(1/0);
int j = qr.update(con,sql2, 1000, "jerry");
System.out.println("i = " + i);
System.out.println("j = " + j);
//提交事务,并悄悄的关闭资源
DbUtils.commitAndCloseQuietly(con);
}catch (Exception ex){
ex.printStackTrace();
//回滚事务
DbUtils.rollbackAndCloseQuietly(con);
}finally {
//释放资源
DbUtils.closeQuietly(con);
}
}