当前位置: 首页 > news >正文

5分钟了解,Mysql事务事务隔离级别

01引言

上一节主要介绍了声明式事务,其中的一个属性就是事务的隔离级别isolation。今天我们以Mysql为例,深入介绍一下事务的隔离隔离级别。

02 隔离级别概述

事务的隔离级别,是为了解决并发问题而设定的。不同的隔离级别,并发条件下会发生不同的问题。主要问题有:

  • 脏读:读取到其他事务未提交的数据
  • 不可重复读:同一事务内多次读取同一条数据,因其他事务的修改或删除导致结果不一致。
  • 幻读:同一事务内多次按相同条件查询,行记录不一致

2.1 读未提交

READ UNCOMMITTED,读未提交,可以读到别人没有提交的事务数据。最低等级的隔离级别,属于无锁机制,自然性能也是最好的。但是容易产生脏读、不可重复读、幻读这些问题。这里级别问题较多,一般不会使用。

简单案例:

A将ID为1的记录的余额字段由原来的200改成了100,这个时候还没有提交事务。

这时,B又查询ID为1的记录,他查到的余额字段的结果就是100

2.2 读已提交

READ COMMITTED,读已提交,只能读到事务提交的数据。比READ UNCOMMITTED的隔离高一个等级,属于行级锁。可以避免脏读。但是无法避免不可重复读、幻读这些问题。

简单案例:

同读已提交的案例,A事务没有提交之前,B查询的结果就是200。只有A提交了事务,B才能读到余额200。

2.3 可重复读

REPEATABLE READ,可重复读,同一个事务中读取到的结果一致。比READ COMMITTED的隔离高一个等级,属于行级锁+间隙锁。可以避免脏读、不可重复读,但是无法解决幻读的问题。这个是Mysql默认的隔离级别。

SELECT @@transaction_isolation;

简单案例:

A先开启了事务,查询当天的数据库的记录数,假如是100条,这是时候还没有提交事务。

B新增了一条记录,并提交了事务。A这是再同一个事务中再次查询记录数,还是100条,看不到B新增的记录。

2.4 串行化

SERIALIZABLE,串行化。最严格的隔离级别。只要有事务发生,统统等待,一个一个顺序执行,完全避免并发问题。性能当然也是最差的。

03 案例分析

3.1 脏读

Dirty Read,脏读。在读未提交的隔离级别下发生,读取到其他事务未提交的数据,事务未提交的数据被称为脏数据。

-- 事务A(写)
START TRANSACTION;
UPDATE account SET balance = 1500 WHERE id = 1; -- 未提交-- 事务B(读)
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
SELECT balance FROM account WHERE id = 1; -- 读到1500(脏数据)

后果: 事务B基于无效数据决策(如允许转账),若事务A回滚导致数据不一致。

**解决方案:**只能升级数据库的隔离级别,升级至READ COMMITTED

3.2 不可重复读

Non-Repeatable Read, 不可重复读。在读未提交、读已提交的隔离级别下可能发生。

-- 事务A
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT balance FROM account WHERE id = 1; -- 第一次:1000-- 事务B提交更新
UPDATE account SET balance = 1500 WHERE id = 1;
COMMIT;-- 事务A再次读取
SELECT balance FROM account WHERE id = 1; -- 结果变为1500!
COMMIT;

后果: 事务内相同查询结果不一致(如对账失败)。
解决方案: 升级隔离级别,使用REPEATABLE READ

3.3 幻读

Phantom Read,幻读。在读未提交、读已提交、可重复读的隔离级别下可能发生。

-- 事务A
START TRANSACTION; -- 默认REPEATABLE READ
SELECT * FROM account WHERE balance >= 1000; -- 返回id=1,2-- 事务B插入新记录并提交
INSERT INTO account VALUES (3, 3000);
COMMIT;-- 事务A再次查询
SELECT * FROM account WHERE balance >= 1000; 
-- 仍只返回id=1,2,3 → 出现"幻读"
COMMIT;

后果: 行记录的这种影响其实并不是太影响结果,大部分情况下都是可接受的。一般情况下是不需要的解决的。

3.4 不可重复读和幻读的区别

不可重复读和幻读都是在同一个事务下,多次获取的结果不同。但是又有根本的区别

  • 不可重复读:针对单条数据的修改冲突。

  • 幻读:针对结果集范围的新增或删除冲突,表现为行数增减或新行出现

04 小结

数据库的隔离级别影响着数据查询的结果,在满足业务需求的情况下,选择合适的隔离级别,可以提高数据的读写性能。但是我们一般选默认就够了,因为它已经足够好了

http://www.xdnf.cn/news/871633.html

相关文章:

  • tensorflow image_dataset_from_directory 训练数据集构建
  • 使用 Python 的 psutil 库进行系统资源监控
  • Webpack搭建本地服务器
  • Unity3D 逻辑代码性能优化策略
  • Linux kill 暂停命令
  • 跟着deepseek浅学分布式事务(2) - 两阶段提交(2PC)
  • 人工智能:网络安全的“智能守护者”
  • 录制mp4
  • Kali Linux 安全工具解析
  • Ros(控制机器人运动)
  • .NET 原生驾驭 AI 新基建实战系列(四):Qdrant ── 实时高效的向量搜索利器
  • JVMTI 在安卓逆向工程中的应用
  • 【Oracle】存储过程
  • 纹理压缩格式优化
  • OpenCV 自带颜色表实现各种滤镜
  • 【Netty源码分析总结】
  • 使用 Unstructured 开源库快速入门指南
  • 机器学习:聚类算法
  • Python爬虫:trafilatura 的详细使用(快速提取正文和评论以及结构,转换为 TXT、CSV 和 XML)
  • Day44打卡 @浙大疏锦行
  • 01-Redis介绍与安装
  • pyqt5 安装失败
  • 查看服务应用是否有跑起来命令
  • 机器学习算法分类
  • 3D旋转动态爱心 - Python创意代码
  • MySQL ACID 面试深度解析:原理、实现与面试实战
  • Pytest+Selenium UI自动化测试实战实例
  • MCP:AI应用的通用接口,如何重塑大模型与外部系统的连接?
  • 小米又开源了,一个多模态大模型 + 一个生不逢时的推理大模型
  • CppCon 2015 学习:Bridging Languages Cross-Platform