MySQL InnoDB引擎 事务隔离级别

在 MySQL 的 InnoDB 存储引擎中,定义了四种不同的事务隔离级别,这些隔离级别控制着事务之间的可见性和并发操作的行为,每种隔离级别在数据一致性和并发性能之间进行了不同的权衡。

1. 读未提交(Read Uncommitted)

定义:这是最低的隔离级别,一个事务可以读取另一个事务尚未提交的数据变更。也就是说,在这种隔离级别下,事务可以看到其他事务中未提交的修改,存在脏读的风险。

优点:并发性能最高,因为读操作不会被写操作阻塞,读写操作可以最大程度地并发执行。

缺点:会出现脏读、不可重复读和幻读问题。脏读是指一个事务读取到了另一个事务未提交的数据,如果该事务回滚,那么读取到的数据就是无效的。

示例:

复制代码
-- 会话 1
START TRANSACTION;
UPDATE users SET balance = balance - 100 WHERE id = 1;
-- 此时会话 2 可以读取到会话 1 未提交的修改

-- 会话 2
START TRANSACTION;
SELECT balance FROM users WHERE id = 1; -- 可能读到未提交的余额变化

2. 读已提交(Read Committed)

定义:一个事务只能读取另一个事务已经提交的数据变更。这避免了脏读问题,但仍然可能出现不可重复读和幻读问题。

优点:避免了脏读,保证了读取到的数据都是已经提交的有效数据,数据的可靠性有所提高。

缺点:存在不可重复读和幻读问题。不可重复读是指在一个事务内多次读取同一数据时,由于其他事务的修改,导致每次读取的结果不一致。

示例:

复制代码
-- 会话 1
START TRANSACTION;
UPDATE users SET balance = balance - 100 WHERE id = 1;
COMMIT;

-- 会话 2
START TRANSACTION;
SELECT balance FROM users WHERE id = 1; -- 第一次读取
-- 此时会话 1 提交修改
SELECT balance FROM users WHERE id = 1; -- 第二次读取,结果可能不同

3. 可重复读(Repeatable Read)

定义:这是 InnoDB 存储引擎的默认隔离级别。在一个事务内多次读取同一数据时,会保证读取到的结果是一致的,避免了脏读和不可重复读问题,但在某些情况下仍可能出现幻读。InnoDB 通过 MVCC(多版本并发控制)和间隙锁来实现该隔离级别。

优点:提供了较高的数据一致性,适合大多数业务场景。在同一个事务中,多次读取相同的数据会得到相同的结果,保证了数据的稳定性。

缺点:虽然通过 MVCC 避免了大部分幻读,但在某些复杂的查询场景下仍可能出现幻读问题。幻读是指在一个事务内,当执行范围查询时,由于其他事务插入了符合查询条件的新数据,导致多次查询的结果集不一致。

示例:

复制代码
-- 会话 1
START TRANSACTION;
SELECT * FROM users WHERE age > 20; -- 第一次查询
-- 此时会话 2 插入一条 age > 20 的记录并提交
SELECT * FROM users WHERE age > 20; -- 第二次查询,可能会出现新增的记录

4. 串行化(Serializable)

定义:这是最高的隔离级别,事务之间会串行执行,一个事务执行时会锁定所有涉及的数据,其他事务必须等待该事务完成后才能执行。这避免了脏读、不可重复读和幻读问题,提供了最强的数据一致性保证。

优点:提供了最高的数据一致性,完全避免了并发问题,适合对数据一致性要求极高的场景,如金融交易系统。

缺点:并发性能最低,因为事务之间是串行执行的,会导致大量的锁等待,降低了系统的吞吐量。

示例:

复制代码
-- 会话 1
START TRANSACTION;
SELECT * FROM users WHERE id = 1 FOR UPDATE; -- 对查询结果加锁
-- 此时会话 2 对 users 表的相关操作会被阻塞,直到会话 1 提交或回滚

设置事务隔离级别

可以使用以下 SQL 语句来设置事务隔离级别:

复制代码
-- 设置全局隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL [隔离级别名称];
-- 设置当前会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL [隔离级别名称];

其中,[隔离级别名称] 可以是 READ UNCOMMITTEDREAD COMMITTEDREPEATABLE READSERIALIZABLE

相关推荐
2401_884810742 分钟前
maven笔记
java·笔记·maven
霸王龙的小胳膊3 分钟前
SpringMVC-登录校验
java·mvc
字节源流4 分钟前
【SpringMVC】常用注解:@PathVariable
java·开发语言·servlet
小安同学iter9 分钟前
SpringMVC(五)拦截器
java·开发语言·spring boot·spring·java-ee
Eugene Jou16 分钟前
FlinkSQL实现实时同步和实时统计过程(MySQL TO MySQL)
数据库·mysql·flink·flinksql
栀栀栀栀栀栀22 分钟前
JVM 2015/3/15
java·开发语言·jvm
编程零零七22 分钟前
基于Python+Flask+MySQL+HTML的爬取豆瓣电影top-250数据并进行可视化的数据可视化平台
python·mysql·信息可视化·flask·python教程·python安装
羊思茗52029 分钟前
Spring Boot中@Valid 与 @Validated 注解的详解
java·spring boot·后端
老朋友此林1 小时前
Redisson 实现分布式锁源码浅析
java·redis·分布式
爱分享的淘金达人1 小时前
25年教师资格认定材料及认定详细流程‼
java·python·考研·小程序·tomcat