事务控制TCL(Transaction Control Language)是用于管理数据库事务的一组语句,它的核心作用是保证一组数据库操作要么全部执行成功,要么全部回滚,避免出现数据不一致的情况。事务具备ACID四大特性,分别是原子性、一致性、隔离性和持久性,这也是事务能够保障数据可靠性的基础。

MySQL中的事务控制实现
MySQL中默认情况下,每条SQL语句都是一个独立的事务,执行完会自动提交。如果需要手动控制事务,首先需要关闭自动提交,或者显式开启事务。
MySQL常用事务控制语句
- START TRANSACTION 或 BEGIN:显式开启一个事务
- COMMIT:提交事务,将事务中的所有操作持久化到数据库
- ROLLBACK:回滚事务,撤销事务中所有未提交的操作
- SAVEPOINT 保存点名称:在事务中设置保存点,可以回滚到指定保存点
- ROLLBACK TO 保存点名称:回滚到指定的保存点
MySQL事务控制示例
以下是一个转账场景的事务示例,保证转出和转入操作要么同时成功,要么同时失败:
-- 关闭自动提交,也可以直接用START TRANSACTION开启事务 SET autocommit = 0; -- 开启事务 START TRANSACTION; -- 从A账户扣除100元 UPDATE account SET balance = balance - 100 WHERE user_id = 'A'; -- 给B账户增加100元 UPDATE account SET balance = balance + 100 WHERE user_id = 'B'; -- 如果没有异常,提交事务 COMMIT; -- 如果出现异常,执行回滚 -- ROLLBACK;
JDBC中的事务控制实现
JDBC是Java连接数据库的标准接口,它提供了对应的方法来控制事务,核心是通过Connection对象来操作事务的提交和回滚。
JDBC事务控制核心方法
setAutoCommit(boolean autoCommit):设置是否自动提交事务,传入false表示关闭自动提交,开启手动事务控制commit():提交当前事务rollback():回滚当前事务setTransactionIsolation(int level):设置事务的隔离级别
JDBC事务控制代码示例
同样以转账场景为例,使用JDBC实现事务控制:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcTransactionDemo {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
// 1. 获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_db?useSSL=false", "root", "password");
// 2. 关闭自动提交,开启事务
conn.setAutoCommit(false);
// 3. 创建执行SQL的对象
stmt = conn.createStatement();
// 4. 执行转出操作
String sql1 = "UPDATE account SET balance = balance - 100 WHERE user_id = 'A'";
stmt.executeUpdate(sql1);
// 模拟异常,测试回滚效果
// int a = 1 / 0;
// 5. 执行转入操作
String sql2 = "UPDATE account SET balance = balance + 100 WHERE user_id = 'B'";
stmt.executeUpdate(sql2);
// 6. 没有异常,提交事务
conn.commit();
System.out.println("转账成功,事务已提交");
} catch (Exception e) {
// 7. 出现异常,回滚事务
try {
if (conn != null) {
conn.rollback();
System.out.println("转账失败,事务已回滚");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
// 8. 关闭资源
try {
if (stmt != null) {
stmt.close();
}
if (conn != null) {
// 恢复自动提交设置
conn.setAutoCommit(true);
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
事务隔离级别说明
事务隔离级别决定了不同事务之间的可见性,MySQL支持四种隔离级别,不同级别可以解决不同的并发问题:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED(读未提交) | 可能 | 可能 | 可能 |
| READ COMMITTED(读已提交) | 不可能 | 可能 | 可能 |
| REPEATABLE READ(可重复读,MySQL默认) | 不可能 | 不可能 | 可能 |
| SERIALIZABLE(串行化) | 不可能 | 不可能 | 不可能 |
在JDBC中可以通过conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ)来设置对应的隔离级别,实际开发中需要根据业务场景选择合适的隔离级别,平衡数据一致性和性能。