MySQL事务

掌握事务概念、ACID属性和事务控制语句

什么是事务?

事务是数据库操作的基本单位,是一组要么全部执行成功,要么全部不执行的SQL语句集合。事务确保数据库从一个一致性状态转换到另一个一致性状态。

事务的ACID属性

  • 原子性(Atomicity) - 事务中的所有操作要么全部完成,要么全部不完成
  • 一致性(Consistency) - 事务执行前后,数据库必须保持一致性状态
  • 隔离性(Isolation) - 多个事务并发执行时,彼此之间相互隔离
  • 持久性(Durability) - 事务提交后,对数据库的修改是永久性的

事务控制语句

开始事务

SQL示例
START TRANSACTION;
-- 或者
BEGIN;

提交事务

SQL示例
COMMIT;

回滚事务

SQL示例
ROLLBACK;

设置保存点

SQL示例
SAVEPOINT savepoint_name;

回滚到保存点

SQL示例
ROLLBACK TO savepoint_name;

事务示例

银行转账事务

SQL示例
START TRANSACTION;

-- 从账户A扣款
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

-- 向账户B存款
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

-- 如果两个操作都成功,提交事务
COMMIT;
注意:如果在事务执行过程中发生错误,可以使用ROLLBACK回滚所有操作,确保数据的一致性。

事务隔离级别

MySQL支持四种事务隔离级别:

隔离级别 描述 可能的问题
READ UNCOMMITTED 读取未提交数据 脏读、不可重复读、幻读
READ COMMITTED 读取已提交数据 不可重复读、幻读
REPEATABLE READ 可重复读(MySQL默认) 幻读
SERIALIZABLE 串行化 无并发问题,但性能最低

设置隔离级别

SQL示例
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

自动提交模式

MySQL默认启用自动提交模式,每个SQL语句都会自动提交。可以关闭自动提交来手动控制事务:

SQL示例
-- 关闭自动提交
SET autocommit = 0;

-- 开启自动提交
SET autocommit = 1;

并发问题

当多个事务并发执行时,可能会出现以下问题:

  • 脏读 - 读取到另一个事务未提交的数据
  • 不可重复读 - 同一事务中多次读取同一数据,结果不一致
  • 幻读 - 同一事务中多次查询,返回的行数不一致

并发问题示例

SQL示例
-- 事务A
START TRANSACTION;
SELECT * FROM users WHERE id = 1; -- 读取数据

-- 事务B
START TRANSACTION;
UPDATE users SET name = '新名字' WHERE id = 1;

-- 事务A再次读取同一数据,如果隔离级别低,可能会看到不一致的数据
SELECT * FROM users WHERE id = 1;

事务最佳实践

  • 保持事务尽可能短,减少锁定时间
  • 避免在事务中进行用户交互
  • 使用适当的隔离级别平衡一致性和性能
  • 在应用程序中正确处理事务失败
  • 使用保存点处理复杂事务
最佳实践:对于需要多个操作作为一个整体执行的场景,务必使用事务来保证数据的一致性。

下一步学习

掌握了事务概念后,您可以继续学习:

  • MySQL索引 - 学习如何创建和使用索引提高查询性能
  • MySQL视图 - 了解如何创建和使用数据库视图
  • 存储过程 - 学习创建和使用存储过程