Mysql如何实现事务隔离

来源:Golang编程网作者:松本一香头衔:网络博主
导读:本期聚焦于小伙伴创作的《Mysql如何实现事务隔离》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Mysql如何实现事务隔离》有用,将其分享出去将是对创作者最好的鼓励。

Mysql的事务隔离是通过不同的隔离级别来控制多个事务同时操作数据时的一致性问题,避免出现脏读、不可重复读、幻读等异常情况,其实现依赖锁机制和MVCC多版本并发控制两种核心技术。

Mysql如何实现事务隔离

事务隔离级别

Mysql支持四种标准的事务隔离级别,不同级别解决的并发问题不同,级别越高数据一致性越好,但并发性能会有所下降,四种级别如下:

隔离级别脏读不可重复读幻读
READ UNCOMMITTED(读未提交)存在存在存在
READ COMMITTED(读已提交)不存在存在存在
REPEATABLE READ(可重复读)不存在不存在不存在(InnoDB引擎通过间隙锁解决)
SERIALIZABLE(串行化)不存在不存在不存在

可以通过如下语句查看和设置当前会话的事务隔离级别:

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

-- 设置当前会话隔离级别为可重复读
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

锁机制实现事务隔离

Mysql的InnoDB引擎通过不同类型的锁来控制并发访问,是事务隔离的基础实现方式:

行锁与表锁

行锁是锁定某一行数据的锁,不同事务可以同时操作不同行的数据,并发性能更好;表锁是锁定整张表,同一时间只有一个事务能操作表,并发性能较差。InnoDB默认使用行锁,MyISAM引擎只支持表锁。

共享锁与排他锁

  • 共享锁(S锁):事务读取数据时加的锁,多个事务可以同时持有同一行数据的共享锁,但是不能加排他锁。
  • 排他锁(X锁):事务修改数据时加的锁,加了排他锁的数据其他事务不能加任何锁,也不能读取修改。

可以通过以下语句手动加锁:

-- 加共享锁
SELECT * FROM user WHERE id = 1 LOCK IN SHARE MODE;

-- 加排他锁
SELECT * FROM user WHERE id = 1 FOR UPDATE;

间隙锁

间隙锁是InnoDB在REPEATABLE READ级别下为了解决幻读新增的锁,锁定的是索引记录之间的间隙,防止其他事务在这个间隙插入新数据。比如执行SELECT * FROM user WHERE id > 10 AND id < 20 FOR UPDATE时,会锁定id在10到20之间的所有间隙,其他事务无法插入id在这个范围的记录。

MVCC实现事务隔离

MVCC即多版本并发控制,是InnoDB实现READ COMMITTED和REPEATABLE READ级别的核心机制,它不需要加锁就能实现非阻塞的读操作,提升并发性能。

核心原理

MVCC通过在每行数据后保存两个隐藏列实现:trx_id记录最后一次修改该行的事务ID,roll_pointer指向该行之前的版本在undo log中的位置。每次修改数据时,都会生成一个新的版本,旧版本保存在undo log中。

Read View

Read View是事务执行读操作时生成的快照,里面记录了当前活跃的事务ID列表、最小活跃事务ID、最大事务ID等信息。读数据时会对比数据的trx_id和Read View的信息,判断哪个版本的数据对当前事务可见:

  • 如果数据的trx_id小于Read View的最小活跃事务ID,说明该版本数据是已提交事务修改的,可见。
  • 如果数据的trx_id在活跃事务ID列表中,说明修改该数据的事务还未提交,不可见,需要找旧版本。
  • 如果数据的trx_id大于Read View的最大事务ID,说明修改该数据的事务是在当前Read View生成之后才开始的,不可见,需要找旧版本。

READ COMMITTED级别下,每次读操作都会生成新的Read View,所以能读到其他事务最新提交的数据;REPEATABLE READ级别下,事务第一次读操作时生成Read View,之后每次读都复用这个Read View,所以能保证多次读到的数据一致。

不同隔离级别示例

创建测试表并插入数据:

CREATE TABLE test_isolation (
  id INT PRIMARY KEY,
  num INT
) ENGINE=InnoDB;

INSERT INTO test_isolation VALUES (1, 10);

在READ COMMITTED级别下,事务A执行修改但未提交,事务B能读到修改前的数据,事务A提交后事务B能读到修改后的数据:

-- 事务A
START TRANSACTION;
UPDATE test_isolation SET num = 20 WHERE id = 1;

-- 事务B(隔离级别为READ COMMITTED)
START TRANSACTION;
SELECT num FROM test_isolation WHERE id = 1; -- 结果为10,未读到未提交的修改
COMMIT;

-- 事务A提交
COMMIT;

-- 事务B再次查询
START TRANSACTION;
SELECT num FROM test_isolation WHERE id = 1; -- 结果为20,读到了已提交的修改
COMMIT;

在REPEATABLE READ级别下,事务A修改提交后,事务B在同一个事务内多次查询得到的结果一致:

-- 事务A
START TRANSACTION;
UPDATE test_isolation SET num = 30 WHERE id = 1;
COMMIT;

-- 事务B(隔离级别为REPEATABLE READ)
START TRANSACTION;
SELECT num FROM test_isolation WHERE id = 1; -- 结果为20
SELECT num FROM test_isolation WHERE id = 1; -- 结果仍为20,即使事务A已经提交修改
COMMIT;

Mysql事务隔离ACID锁机制MVCC修改时间:2026-07-02 16:00:19

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。