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

事务的隔离级别

MYSQL数据库隔离级别与并发问题分析

在数据库的并发控制中,事务隔离级别(Transaction Isolation Level)和读类型(Read Types)对解决并发问题至关重要。常见的并发问题包括脏读不可重复读幻读。不同的隔离级别和读类型使用不同的锁机制来解决这些问题。

隔离级别与并发问题

以下表格展示了在不同的数据库隔离级别下,快照读当前读两种读类型对脏读、不可重复读和幻读的影响:

隔离级别读类型脏读不可重复读幻读
读未提交快照读会发生会发生会发生
当前读不会发生(由于读取记录时加锁,其他事务无法读取该数据,必须是两个事务都执行SELECT ... FOR UPDATE加排它锁)不会发生(读取时加锁,其他事务无法修改该数据,FOR UPDATELOCK IN SHARE MODE均可)会发生(记录锁无法解决)
读已提交快照读不会发生(MVCC机制确保读取已提交的数据)会发生(每次读取会生成新的快照)会发生(记录锁无法解决)
当前读不会发生(通过加锁机制防止脏读)不会发生(排它锁确保数据不可修改)会发生(记录锁无法解决)
可重复读快照读不会发生(MVCC机制确保读取数据的一致性)不会发生(MVCC生成一次快照)会发生(部分情况通过MVCC可以解决)
当前读不会发生(通过加锁机制确保数据一致性)不会发生(通过加锁机制确保数据一致性)不会发生(通过间隙锁解决)
串行化快照读不会发生(自动转换为当前读)不会发生(自动转换为当前读)不会发生(自动转换为当前读)
当前读不会发生(加锁机制确保数据一致性)不会发生(加锁机制确保数据一致性)不会发生(加锁机制确保数据一致性)

详细解释与分析

1. 读未提交(Read Uncommitted)

在该隔离级别下,事务可以读取未提交的数据,即脏读是允许发生的。因此,事务1可以读取到事务2未提交的更改,即使事务2随后回滚,事务1读取到的数据也可能不一致。除此之外,不可重复读幻读也是允许发生的,因为没有足够的锁机制来保证数据的一致性。

  • 快照读:在读取时不会加锁,其他事务可以修改数据,导致脏读、不可重复读和幻读的发生。
  • 当前读:通过SELECT ... FOR UPDATELOCK IN SHARE MODE对数据加锁,解决了脏读和不可重复读,但仍然无法解决幻读问题,因为记录锁无法防止其他事务插入数据。
2. 读已提交(Read Committed)

在该隔离级别下,事务只能读取已提交的数据,避免了脏读的发生。但是,由于每次读取会生成新的快照,不可重复读仍然可能发生。

  • 快照读:每次读取会生成新的快照,导致可能出现不同的读取结果。
  • 当前读:通过加锁机制(排它锁)防止数据被修改,避免了不可重复读,但依然无法解决幻读。
3. 可重复读(Repeatable Read)

该隔离级别通过MVCC机制确保在同一事务内读取到的数据始终一致,避免了脏读不可重复读。但是,幻读依然可能发生,部分情况可以通过MVCC来部分解决。

  • 快照读:MVCC机制保证了每次读取数据时返回的是事务开始时的一致性快照,避免了不可重复读和脏读,解决了大部分的幻读。如果事务1和事务2开启,事务1进行查询,事务2插入数据后提交,事务1再对事务2提交的数据进行了一个update操作,再去查询就会发生幻读
  • 当前读:通过加锁机制(间隙锁)确保数据一致性,避免了不可重复读和幻读。
4. 串行化(Serializable)

该隔离级别是最严格的,事务会完全串行化执行,自动将读取操作转换为当前读,避免了所有并发问题:脏读不可重复读幻读。它通过强制加锁,确保事务执行时不会有其他事务插入数据或修改数据。

  • 快照读:自动转换为当前读,保证了数据一致性。
  • 当前读:加锁机制确保事务操作时不会受到其他事务影响,从而避免了脏读、不可重复读和幻读。

锁机制的作用

  • 记录锁:在读已提交、可重复读隔离级别下,记录锁用于防止其他事务对正在读取的数据进行修改,但无法防止幻读,因为它无法阻止其他事务插入新的数据。
  • 间隙锁:在可重复读和串行化隔离级别下,使用间隙锁来防止幻读。间隙锁锁定查询范围内的数据区间,从而避免其他事务在该区间插入数据。
  • 排它锁(Exclusive Lock)与共享锁(Shared Lock):在当前读中,排它锁用于保证事务独占数据,而共享锁则允许其他事务进行读取,但不允许修改数据。

快照读和当前读的区别

快照读(Snapshot Read):快照读是基于MVCC(多版本并发控制)机制的一种读取方式。每个事务在启动时会创建一个自己的数据快照,这个快照是事务开始时数据库中所有数据的快照(即该事务看到的数据版本)。事务读取的数据版本就是这个快照中对应的版本,而不是当前数据库的最新版本。快照读不加锁,因此不会阻塞其他事务的操作。

当前读(Current Read):当前读是指读取数据库当前最新的数据,通常是指最新提交的数据。当前读需要加锁机制,通常使用排它锁(Exclusive Lock)或共享锁(Shared Lock)来确保数据的读取与修改的一致性。当前读会受到其他事务的影响,数据可能会被修改或者插入,因此当前读通常是一个加锁的操作

for update行锁对其他事务读操作的影响

#开启一个事务
begin;
select * from t_user_info for update;
//此时没有提交

#同时再开启一个事务
begin;
select * from t_user_info for update;
commit;

这种情况下,第二个事务是会被阻塞的

#开启一个事务
begin;
select * from t_user_info for update;
//此时没有提交

#同时再开启一个事务
begin;
select * from t_user_info;
commit;

这种情况下,第二个事务不会被阻塞的
#开启一个事务
begin;
select * from t_user_info for update;
//此时没有提交

#同时再开启一个事务
begin;
select * from t_user_info lock in share mode;
commit;
这种情况下,第二个事务是会被阻塞的

排它锁会阻止其他事务对数据加共享锁排它锁

共享锁允许其他事务也加共享锁,但会阻止其他事务对数据加排它锁


http://www.kler.cn/a/564605.html

相关文章:

  • 深度学习中的 shape以及 axis的含义以及使用
  • java23种设计模式-状态模式
  • vue框架后遗症∶被遗忘的dom操作
  • 蓝耘科技发布DeepSeek满血版:引领AI推理革新,开启智慧新时代
  • 网络通信库
  • 时序论文40 | 将不规则采样时间序列转换为图像,利用预训练视觉Transformer进行分类
  • IO 和 NIO 有什么区别?
  • Linux:Shell环境变量与命令行参数
  • 29.[前端开发-JavaScript基础]Day06-创建对象-对象补充-包装类型-数组Array
  • 神经网络 - 函数饱和性、软性门、泰勒级数
  • CSS 实现波浪效果
  • Python 的基础语法
  • 基于 ‌MySQL 数据库‌对三级视图(用户视图、DBA视图、内部视图)的详细解释
  • React + TypeScript 复杂布局开发实战
  • 【落羽的落羽 数据结构篇】链式结构的二叉树
  • 计算机视觉 |解锁视频理解三剑客——SlowFast
  • mysql架构查询执行流程(图解+描述)
  • Redis离线安装(内网,源码安装)
  • 小白向-python实现插入排序算法
  • 大白话React Hooks,新特性怎么用?