前言
昨天总结了JDBC编码具体步骤,今天我们来说一下JDBC事务、批处理以及JDBC连接池的相关概念及用法,(注:笔者所有代码语句针对MySQL数据库实现)
一、JDBC事务
引出:我们先来看一个问题,假设我们的数据库中有一张余额表,里面有两条记录,如下表:
+----+-----------+---------+
| id | name | balance |
+----+-----------+---------+
| 1 | 马云 | 2800 |
| 2 | 马化腾 | 10100 |
+----+-----------+---------+
现在有如下需求:我们需要将马云的100块转给马化腾,理想结果是马云的balance=2700,而马化腾的balance=10200;我们在idea代码中模拟一下:
@Test
public void noTransaction(){
//1.得到连接
Connection connection = null;
//2.组织sql语句
String sql = "Update account2 set balance = balance-100 where id=1";
String sql2 = "Update account2 set balance = balance+100 where id=2";
PreparedStatement preparedStatement =null;
//3.创建PreparedStatement对象
try {
connection = JDBCUtils.getConnection();//默认情况下,connection是默认自动提交
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();//第一条
int i =1/0;
preparedStatement = connection.prepareStatement(sql2);
preparedStatement.executeUpdate();//第二条
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
//关闭资源
JDBCUtils.close(null,preparedStatement,connection);
}
}
注:JDBCUtils工具类是完成对连接数据库,和关闭资源的一系列操作,这里不作详细讲述
如果try-catch代码块中没有 int i =1/0;这条语句,很显然两条语句是可以执行成功,测试结果如下表:
但是如果执行过程中有int i =1/0,就会抛出一个java.lang.ArithmeticException: / by zero 异常,try-catch语句中,只要有代码抛出异常,下面的代码将不会执行,所以出现了一个问题:就是马云的一百块确实转出去了,但是马化腾没有收到100块,这100块凭空消失了,这在我们实际开发中是一个很严重的错误,比如在银行转账取款等问题,可能有小伙伴会说,那为什么要写这个异常呢,你不写它,马化腾不就收到了吗?这里笔者只想从这个问题抛出事务的作用,下面笔者用事务来解决这个问题。
JDBC事务基本介绍
1.JDBC程序中当一个Connection对象创建时,默认情况下时自动提交事务:每次执行一个sql语句时,如果执行成功,就会向数据库自动提交,而不能回滚
2.JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务
3.调用Connection当setAutoCommit(false) 可以取消自动提交事务
4.在所有的SQL语句都成功执行后,调用Commit():方法提交事务
5.在其中某个操作失败或出现异常时,调用rollback():方法回滚事务
相信大家看到这里对事务还是有点模模糊糊的,下面笔者用代码解决上面转账的问题。直接上代码!
@Test
public void useTransaction(){
//1.得到连接
Connection connection = null;
//2.组织sql语句
String sql = "Update account2 set balance = balance-100 where id=1";
String sql2 = "Update account2 set balance = balance+100 where id=2";