JDBC-事务
JDBC-事务
MySQL 事务主要用于处理操作量大,复杂度高的数据
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
数据库中有很多关于事务的命令
命令 | 说明 |
---|---|
SHOW VARIABLES LIKE 'autocommit' | 查看当前连接中事物的提交方式(ON自动提交 OFF关闭自动提交) |
SET autocommit = FALSE | 设置当前连接事务提交方式为手动提交 |
COMMIT | 提交事务 |
ROLLBACK | 回滚事务 |
事务的回滚
如果有两条语句要执行,可以看数据的受影响行数
如果当前连接受影响行数小于预期受影响行数,就说明有语句执行失败,需要事务回滚
JDBC工具类的优化
对工具类进行修改,在回收连接前开启自动提交(关闭事务),再将连接回收
public static void close() {
try {
//从theadlocal中获取到连接,判断是否有线程
//如果有,该连接回收到连接池,并将threadlocal中的连接移除
Connection connection = threadLocal.get();
if (connection != null) {
threadLocal.remove();
//开启自动提交(关闭事务)
connection.setAutoCommit(true);
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
对BaseDAO进行修改,在两个方法中对工具类的连接的回收加以判定
if (connection.getAutoCommit())
{
JDBCUtilV2.close();
}
这样操作之后,开启事务(关闭自动提交)时,将不会由BaseDAO接管连接的回收
即不会再执行完SQL方法时自动回收链接,需要在业务层自己操作回收链接
业务层代码
在业务层中,我们有三个关键的操作
- 开启事务(关闭自动提交):connection.setAutoCommit(false)
- 提交事务:connection.commit()
- 回滚事务:connection.rollback()
注:事务的开启,connection.setAutoCommit是针对这一连接的,要保证业务连接的唯一性,我们需要用到JDBCUtilV2中的threadLocal
@Test
public void testTransaction(){
UserDao userDao = new UserDaoImpl();
Connection connection = null;
try {
connection = JDBCUtilV2.getConnection();
connection.setAutoCommit(false);//关闭自动提交(开启事务)
userDao.addMoney(1,200);
userDao.addMoney(2,200);
connection.commit();//提交事务
} catch (SQLException e) {
try {
connection.rollback();//当出现异常时,事务自动回滚
} catch (SQLException ex) {
throw new RuntimeException(e);
}
throw new RuntimeException(e);
} finally {
//BaseDAO检测到事务开启(自动提交关闭),则不会自动回收连接,所以在Finally中回收连接
JDBCUtilV2.close();
}