侧边栏壁纸
博主头像
ProSayJ 博主等级

Talk is cheap. Show me the code.

  • 累计撰写 43 篇文章
  • 累计创建 16 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

29-SQL标准中的4个事务隔离级别

YangJian
2025-06-28 / 0 评论 / 0 点赞 / 14 阅读 / 0 字

通过 前一章 [ 28-MySQL 多事务并发执行的数据一致性问题 ] 的讨论,可能会遇到的几种问题,包括脏写、脏读、不可重复读和幻读。这些问题的根本原因是由于多个事务之间的数据竞争,导致事务间没有适当的隔离。

为了避免这些并发问题,SQL标准规定了几种事务隔离级别。需要注意的是,讨论的是SQL标准中的事务隔离级别,而不是MySQL的具体实现。MySQL在实现这些隔离级别时可能会有一些不同,我们将在后面详细探讨。

SQL标准中规定了四种事务隔离级别,这四种级别决定了多个并发事务如何隔离,从而减少并发问题的发生。它们分别是:

1. Read Uncommitted(读未提交-RU):

在这个级别下,脏写是允许的。意味着两个事务在未提交时,能同时修改同一行数据。这个级别可能会导致脏写、脏读、不可重复读和幻读 所有并发修改的异常问题。这种隔离级别对数据库的并发控制非常松散,可以说几乎没有并发控制,一般情况下不推荐使用。

2. Read Committed(读已提交-RC):

[ 重点 ]

在这个级别下,脏写和脏读是不会发生的。也就是说,你不会看到其他事务尚未提交的修改。但不可重复读和幻读问题仍然可能发生。因为一旦其他事务提交了数据,当前事务会读取到这些提交的数据,导致多次查询的结果可能不一致。该级别常见的缩写是RC,如果在团队中讨论时听到别人提到“把事务隔离级别设置成RC”,意味着使用的是“读已提交”级别。

3. REPEATABLE READ(可重复读-RR):

[ 重点 by the way mysql 事务默认隔离级别 并且 mysql 在 RR 解决了 幻读 ]

在这个级别下,脏写、脏读、不可重复读是不会发生的。具体来说,当事务A开始执行后,即使其他事务修改了数据并提交,事务A仍然只能读取到它开始时的数据。这意味着,如果事务A在执行过程中多次查询同一数据,它每次都会得到相同的值,而不会受到其他事务提交的影响。因此,事务A在执行期间读取到的值始终保持一致。REPEATABLE READ 隔离级别就确保了事务A在整个执行期间,查询到的同一数据值是一致的,不会受到其他事务提交的修改影响。

4. SERIALIZABLE(串行化):

这种级别是最严格的,基本上不允许多个事务并发执行。所有事务必须按照顺序执行:事务A先执行并提交,然后是事务B,最后是事务C,依此类推。

由于事务都是串行执行的,所以自然不存在并发的情况,幻读和其他事务并发问题根本无法发生。因为事务间没有交集,每个事务都是独立执行的。

然而,SERIALIZABLE级别的性能非常差,极少在实际开发中使用。原因很简单,事务必须串行执行,可能导致数据库的并发性能极为低下,尤其是在高并发的场景下,性能几乎无法接受。

5. 总结

SQL 标准中定义了四种事务隔离级别,每个隔离级别对并发事务的控制程度不同,因此解决脏读、脏写、不可重复读和幻读的能力也不同。

  • SERIALIZABLE是最高级别的事务隔离,但由于它对性能的巨大影响,除非极少数特殊场景,一般很少使用。

  • RC(读已提交)和RR(可重复读)是最常见的,大家在日常开发中会更常用到这两种隔离级别。

下面是一个表格,列出了不同事务隔离级别能解决的并发问题:

事务隔离级别

解决脏读

解决脏写

解决不可重复读

解决幻读

读未提交(RU)

读已提交(RC)

✔️

可重复读(RR)

✔️

✔️

串行化

✔️

✔️

✔️

✔️

解释:

  1. 脏读

  • 脏读发生在事务 A 读取了事务 B 未提交的数据。即事务 A 可能会读取到事务 B 中间状态的数据,这些数据在事务 B 回滚时会消失。

  • 解决能力:从“读已提交”隔离级别开始,事务 A 只能读取事务 B 已提交的数据,因此不再出现脏读。

  1. 脏写

  • 脏写发生在事务 A 修改了事务 B 尚未提交的数据,这种修改可能会被事务 B 回滚,导致事务 A 做出的修改是无效的。

  • 解决能力:只有 串行化 隔离级别能完全避免脏写。在该级别下,事务 A 和事务 B 完全串行执行。

  1. 不可重复读

  • 不可重复读 发生在事务 A 读取了某个数据项,事务 B 在事务 A 期间修改了该数据项,再次读取时,事务 A 读到的数据就发生了变化。

  • 解决能力:从“可重复读”开始,事务 A 在整个事务过程中读取的数据保持一致,不会因其他事务修改而变化,避免了不可重复读。

  1. 幻读

  • 幻读发生在事务 A 读取了某个范围的数据,事务 B 在事务 A 期间插入或删除了数据,使得事务 A 在第二次读取时,得到的数据集与第一次读取时不同。

  • 解决能力串行化 隔离级别解决了幻读问题,确保事务 A 在执行期间其他事务不能插入或删除满足查询条件的数据。

总结:

  1. 读未提交:不解决任何问题,所有并发问题都可能发生。

  2. 读已提交:避免脏读,但可能会有脏写、不可重复读和幻读。

  3. 可重复读:避免脏读和不可重复读,但可能会有幻读。

  4. 串行化:解决所有并发问题,包括脏读、脏写、不可重复读和幻读。

0

评论区