MySQL InnoDB 的事务机制是其最核心的特性之一,它通过严格遵循 ACID 模型,为数据提供了可靠的并发控制和故障恢复能力。下面从多个维度详细介绍 InnoDB 的事务。


1. 事务的定义

事务是一组原子性的 SQL 操作,要么全部执行成功,要么全部不执行。在 InnoDB 中,事务可以显式开启和结束,也可以隐式地通过自动提交模式管理。


2. ACID 属性与 InnoDB 的实现

属性含义InnoDB 实现方式
原子性事务中的操作要么全部完成,要么全部回滚通过 undo log 记录修改前的旧值,事务回滚时利用 undo log 恢复数据
一致性事务前后数据库的完整性约束不被破坏通过原子性、隔离性、持久性共同保证,同时外键约束、触发器、数据类型检查等也发挥作用
隔离性多个事务并发执行时,相互隔离,不互相干扰通过 MVCC(多版本并发控制)  和 锁机制(行锁、间隙锁、Next-Key 锁)实现不同的隔离级别
持久性事务一旦提交,其修改永久保存,即使系统崩溃也不丢失通过 redo log 实现。提交时先写 redo log(WAL 技术),崩溃恢复时重放 redo log 确保已提交事务的修改不丢失

3. 事务控制语句

sql

-- 显式开启事务
START TRANSACTION;   -- 或 BEGIN;

-- 提交事务(永久生效)
COMMIT;

-- 回滚事务(撤销当前事务所有修改)
ROLLBACK;

-- 设置保存点,实现部分回滚
SAVEPOINT sp1;
ROLLBACK TO SAVEPOINT sp1;
RELEASE SAVEPOINT sp1;

-- 设置自动提交模式(默认开启,每条语句自动提交)
SET autocommit = 0;   -- 关闭自动提交,需手动 COMMIT
SET autocommit = 1;   -- 开启自动提交

4. 事务隔离级别

InnoDB 支持 SQL 标准定义的四种隔离级别,默认使用 REPEATABLE READ

隔离级别脏读不可重复读幻读说明
READ UNCOMMITTED可能可能可能读未提交,最低隔离,一般不使用
READ COMMITTED不可能可能可能Oracle 默认级别,只读已提交数据
REPEATABLE READ不可能不可能可能(InnoDB 通过 MVCC + 间隙锁解决)InnoDB 默认级别,可重复读,避免幻读
SERIALIZABLE不可能不可能不可能强制事务串行执行,读加锁,性能最低
  • 脏读:读到其他事务未提交的数据。
  • 不可重复读:同一事务内两次读同一行数据,结果不一致(因其他事务修改并提交)。
  • 幻读:同一事务内两次执行相同查询,结果集行数不一致(因其他事务插入或删除)。

设置隔离级别

sql

-- 查看当前隔离级别
SELECT @@transaction_isolation;

-- 设置会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

5. MVCC(多版本并发控制)

InnoDB 通过 MVCC 实现高并发下的非锁定读,使得读操作不阻塞写操作,写操作也不阻塞读操作。

  • 实现原理:每行记录隐藏两个列:DB_TRX_ID(最近修改的事务 ID)和 DB_ROLL_PTR(指向 undo log 中旧版本记录的指针)。
  • Read View:事务执行查询时,根据当前系统的活跃事务列表创建一个 Read View,决定哪些版本的数据可见。
  • 在 REPEATABLE READ 下:事务首次读取时创建 Read View,直到事务结束都复用该视图,从而保证可重复读。
  • 在 READ COMMITTED 下:每条语句执行时都重新创建 Read View,因此每次读取可能看到最新的已提交数据。

MVCC 配合 undo log 使得 InnoDB 在大多数读场景下不需要加锁,显著提升并发性能。


6. 锁机制

InnoDB 使用多种锁来保证事务隔离性,锁粒度以行级为主,兼顾表级。

6.1 锁类型

  • 共享锁(S锁) :允许事务读一行,阻止其他事务加排他锁。
    SELECT ... LOCK IN SHARE MODE;
  • 排他锁(X锁) :允许事务读/写一行,阻止其他事务加任何锁。
    SELECT ... FOR UPDATE; 或 DML 语句自动加 X 锁。

6.2 行锁算法

  • Record Lock:锁定单条记录。
  • Gap Lock:锁定索引记录之间的间隙(范围),防止幻读。
  • Next-Key Lock:Record Lock + Gap Lock 的组合,InnoDB 在 REPEATABLE READ 级别下默认使用,锁定一个范围并包含记录本身,有效防止幻读。

6.3 意向锁

表级锁,用于协调行锁和表锁。当加行锁时,InnoDB 自动给表加意向锁,避免其他事务对整个表加锁时遍历所有行。


7. 并发问题与隔离级别的解决

并发问题定义解决方案
脏读读到未提交的数据隔离级别 ≥ READ COMMITTED 时,通过 MVCC 只读已提交版本
不可重复读同一事务内两次读同一行结果不同隔离级别 ≥ REPEATABLE READ 时,通过 MVCC 的 Read View 复用解决
幻读同一事务内两次查询结果集行数不同REPEATABLE READ 下,InnoDB 使用 Next-Key Lock 锁定范围,防止新数据插入;SERIALIZABLE 下通过表级锁避免

8. 事务的自动提交与隐式提交

  • 自动提交模式:默认每个 SQL 语句作为一个事务自动提交。可通过 SET autocommit=0 关闭,此时需要显式 COMMIT。
  • 隐式提交:某些语句(如 DDL 语句 CREATE TABLEALTER TABLETRUNCATE 等)会隐式提交当前事务。

9. 总结

InnoDB 的事务机制通过 undo log 保证原子性和 MVCC,redo log 保证持久性,锁 + MVCC 实现隔离性,从而完整支持 ACID。默认隔离级别 REPEATABLE READ 结合 Next-Key Lock 能有效避免幻读,同时保持较高的并发性能。在实际开发中,合理控制事务大小、隔离级别和锁粒度,是保障数据库性能和一致性的关键。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com