在mysql的实际开发中,经常会遇到需要执行多个关联sql语句的场景,比如转账操作需要先扣除转出方余额,再增加转入方余额,这两个操作必须同时成功或者同时失败,否则就会出现数据错误,这时候就可以用事务来保证操作的原子性。

事务的基本概念
事务是数据库操作的最小工作单元,是一组不可再分的数据库操作序列。事务的原子性指的是事务中的所有操作要么全部执行成功,要么全部执行失败,不会出现部分执行的情况。mysql的事务还遵循ACID特性,分别是原子性、一致性、隔离性、持久性,其中原子性是保证操作完整性的基础。
mysql中使用事务保证原子性的步骤
1. 开启事务
在mysql中,默认情况下每条sql语句都是一个独立的事务,执行完会自动提交。要手动控制事务,首先需要开启事务,有两种常用方式:
- 使用
START TRANSACTION语句开启事务 - 使用
BEGIN语句开启事务
2. 执行事务中的sql操作
开启事务后,执行需要保证原子性的一组sql语句,这些语句不会立即生效,而是暂时保存在事务中。
3. 提交或回滚事务
如果所有sql语句都执行成功,就使用COMMIT语句提交事务,让所有操作永久生效;如果其中某条语句执行失败,就使用ROLLBACK语句回滚事务,撤销所有已经执行的操作,回到事务开启前的状态。
代码示例
以下是一个转账操作的示例,使用事务保证扣除转出方余额和增加转入方余额两个操作要么同时成功,要么同时失败:
-- 开启事务 START TRANSACTION; -- 扣除转出方余额,假设转出方用户id为1,转账金额100 UPDATE user_account SET balance = balance - 100 WHERE user_id = 1; -- 增加转入方余额,假设转入方用户id为2 UPDATE user_account SET balance = balance + 100 WHERE user_id = 2; -- 检查是否有错误,这里模拟如果转出方余额不足的情况 -- 实际开发中可以通过判断受影响行数等方式判断 -- 假设这里发现转出方余额不足,执行回滚 -- ROLLBACK; -- 如果所有操作正常,执行提交 COMMIT;
事务的自动提交设置
mysql有一个autocommit系统变量,默认值为1,也就是自动提交模式。在自动提交模式下,每条单独的sql语句都会自动作为一个事务提交。如果要手动控制事务,可以先关闭自动提交:
-- 查看当前自动提交状态 SELECT @@autocommit; -- 关闭自动提交 SET autocommit = 0; -- 执行事务操作 START TRANSACTION; UPDATE user_account SET balance = balance - 50 WHERE user_id = 1; UPDATE user_account SET balance = balance + 50 WHERE user_id = 2; COMMIT; -- 恢复自动提交 SET autocommit = 1;
注意事项
- 只有支持事务的存储引擎才能使用事务,mysql中InnoDB存储引擎支持事务,MyISAM存储引擎不支持事务,使用前需要确认表的存储引擎类型。
- 事务中尽量不要执行耗时过长的操作,否则会长时间占用数据库资源,影响其他操作的执行。
- 不同的事务隔离级别会影响事务之间的可见性,需要根据实际场景选择合适的隔离级别,避免脏读、不可重复读、幻读等问题。
- 回滚事务只能撤销未提交的事务操作,已经提交的事务无法通过回滚撤销。