事务的4种隔离级别(Isolation Level)分别是什么?

部署运行你感兴趣的模型镜像


事务的4种隔离级别(Isolation Level)分别是什么?

当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性, 所以, 对于不同的事务,采用不同的隔离级别 有不同的结果。

如果不考虑事务的隔离性, 那么 会发生 下表所示的 3 种问题:


不可重复读 是由于 事务并发修改 同一条 记录 导致的 ,要避免这种情况,最简单的方法就是对要修改的记录加锁,这 导致锁竞争加剧 ,影响性能。另一种方法是通过 MVCC 可以在无锁的情况下,避免不可重复读。

幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。



SQL 标准中定义了 4 种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些是在事务内和事务间可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。 SQL 标准定义的四个隔离级别为: Read Uncommitted 未提交读 Read Committed (提交读)、 Repeatable Read (可重复读)、 Serializable (可串行化) ,下面分别介绍。


不同的隔离级别有不同的现象,并有不同的锁 并发机制,隔离级别越高,数据库的并发性 就越差, 4 种事 隔离级别与并发性能的关系:








如果没有事务隔离,会出现什么样的情况?

假设我们现在有这样一张表(T),里面记录了很多牛人的名字,我们不进行事务的隔离看看会发生什么呢?

第一天,事务A访问了数据库,它干了一件事情,往数据库里加上了新来的牛人的名字,但是没有提交事务。

insert into T values (4, '牛D');

这时,来了另一个事务B,他要查询所有牛人的名字。

select Name from T;

这时,如果没有事务之间没有有效隔离,那么事务B返回的结果中就会出现“牛D”的名字。这就是“脏读(dirty read)”。

第二天,事务A访问了数据库,他要查看ID是1的牛人的名字,于是执行了

select Name from T where ID = 1;

这时,事务B来了,因为ID是1的牛人改名字了,所以要更新一下,然后提交了事务。

update T set Name = '不牛' where ID = 1;

接着,事务A还想再看看ID是1的牛人的名字,于是又执行了

select Name from T where ID = 1;

结果,两次读出来的ID是1的牛人名字竟然不相同,这就是不可重复读(unrepeatable read)。

第三天,事务A访问了数据库,他想要看看数据库的牛人都有哪些,于是执行了

select * from T;

这时候,事务B来了,往数据库加入了一个新的牛人。

insert into T values(4, '牛D');

这时候,事务A忘了刚才的牛人都有哪些了,于是又执行了。

select * from T;

结果,第一次有三个牛人,第二次有四个牛人。

相信这个时候事务A就蒙了,刚才发生了什么?这种情况就叫“幻读(phantom problem)”。

为了防止出现脏读、不可重复读、幻读等情况,我们就需要根据我们的实际需求来设置数据库的隔离级别。下面介绍下这方面内容。

数据库事务隔离级别

数据库事务隔离级别分为四种(级别递减):

1、Serializable (串行化):最严格的级别,事务串行执行,资源消耗最大;

2、REPEATABLE READ(重复读) :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。

3、READ COMMITTED (提交读):大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。

4、Read Uncommitted(未提交读) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。

脏读、不可重复读、幻读:

一个数据库可能拥有多个访问客户端,这些客户端并发访问数据库时,若没有采取必要的隔离措施,存在以下问题,这些问题分为5类,包括3类数据读问题:脏读、不可重复读和幻读。两类数据更新问题:第一类丢失更新、第二类丢失更新。

1、脏读

A事务读取B事务尚未提交的更改数据,并在这个数据的基础上进行操作,这时候如果事务B回滚,那么A事务读到的数据是不被承认的。例如常见的取款事务和转账事务:

2、不可重复读

不可重复读是指A事务读取了B事务已经提交的更改数据。假如A在取款事务的过程中,B往该账户转账100,A两次读取的余额发生不一致。

3、幻读

A事务读取B事务提交的新增数据,会引发幻读问题。幻读一般发生在计算统计数据的事务中,例如银行系统在同一个事务中两次统计存款账户的总金额,在两次统计中,刚好新增了一个存款账户,存入了100,这时候两次统计的总金额不一致。

注意:不可重复读和幻读的区别是:前者是指读到了已经提交的事务的更改数据(修改或删除),后者是指读到了其他已经提交事务的新增数据。对于这两种问题解决采用不同的办法,防止读到更改数据,只需对操作的数据添加行级锁,防止操作中的数据发生变化;二防止读到新增数据,往往需要添加表级锁,将整张表锁定,防止新增数据(oracle采用多版本数据的方式实现)。

4、通俗解释:

脏读:所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。

也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。

不可重复读:事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。

也就是说,当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义。

幻读:事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。

也就是说,当前事务读第一次取到的数据比后来读取到数据条目少。

不可重复读和幻读比较:

两者有些相似,但是前者针对的是update或delete,后者针对的insert。

为什么会出现“脏读”?因为没有“select”操作没有规矩。

为什么会出现“不可重复读”?因为“update”操作没有规矩。

为什么会出现“幻读”?因为“insert”和“delete”操作没有规矩。

“读未提(Read Uncommitted)”能预防啥?啥都预防不了。

“读提交(Read Committed)”能预防啥?使用“快照读(Snapshot Read)”,避免“脏读”,但是可能出现“不可重复读”和“幻读”。

“可重复读(Repeated Red)”能预防啥?使用“快照读(Snapshot Read)”,锁住被读取记录,避免出现“脏读”、“不可重复读”,但是可能出现“幻读”。

“串行化(Serializable)”能预防啥?排排坐,吃果果,有效避免“脏读”、“不可重复读”、“幻读”,不过效果谁用谁知道。




About Me

........................................................................................................................

● 本文作者:小麦苗,部分内容整理自网络,若有侵权请联系小麦苗删除

● 本文在itpub( http://blog.itpub.net/26736162 )、博客园( http://www.cnblogs.com/lhrbest )和个人weixin公众号( xiaomaimiaolhr )上有同步更新

● 本文itpub地址: http://blog.itpub.net/26736162

● 本文博客园地址: http://www.cnblogs.com/lhrbest

● 本文pdf版、个人简介及小麦苗云盘地址: http://blog.itpub.net/26736162/viewspace-1624453/

● 数据库笔试面试题库及解答: http://blog.itpub.net/26736162/viewspace-2134706/

● DBA宝典今日头条号地址: http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

........................................................................................................................

● QQ群号: 230161599 (满) 、618766405

● weixin群:可加我weixin,我拉大家进群,非诚勿扰

● 联系我请加QQ好友 646634621 ,注明添加缘由

● 于 2019-03-01 06:00 ~ 2019-03-31 24:00 在魔都完成

● 最新修改时间:2019-03-01 06:00 ~ 2019-03-31 24:00

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

........................................................................................................................

小麦苗的微店 https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麦苗出版的数据库类丛书 http://blog.itpub.net/26736162/viewspace-2142121/

小麦苗OCP、OCM、高可用网络班 http://blog.itpub.net/26736162/viewspace-2148098/

小麦苗腾讯课堂主页 https://lhr.ke.qq.com/

........................................................................................................................

使用 weixin客户端 扫描下面的二维码来关注小麦苗的weixin公众号( xiaomaimiaolhr )及QQ群(DBA宝典)、添加小麦苗weixin, 学习最实用的数据库技术。

........................................................................................................................

欢迎与我联系

 

 



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26736162/viewspace-2638951/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26736162/viewspace-2638951/

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>我们正在讨论MySQL事务隔离级别事务的定义。用户之前的问题是关于K8s和Docker的Namespace区别,但现在转向了MySQL事务。根据引用内容,我们需要解释事务的定义和隔离级别事务的定义:事务数据库操作的最小工作单元,通常包含一个或多个操作,这些操作要么全部成功执行(提交),要么全部失败回滚(回滚)。事务必须满足ACID特性(原子性、一致性、隔离性、持久性)。 隔离级别事务隔离级别定义了多个并发事务之间如何相互隔离,特别是事务对数据修改的可见性。SQL标准定义了四种隔离级别,从低到高依次为:读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)、串行化(SERIALIZABLE)。 根据引用[1]:事务隔离级别决定了多个事务并发执行时,一个事务的修改对其它事务的可见性。隔离级别越高,隔离性越好,但并发性能下降。 引用[3]详细说明了串行化(SERIALIZABLE)隔离级别事务完全串行执行,避免了脏读、不可重复读和幻读,但并发性能最低。 引用[4]提到在分布式事务中(XA事务),InnoDB存储引擎必须使用串行化隔离级别。 此外,引用[2]提到了MVCC(多版本并发控制),它是实现事务隔离级别(特别是可重复读和读已提交)的一种机制。 现在,我们需要结构化回答: 1. 事务定义(ACID) 2. 四种隔离级别的定义和问题(脏读、不可重复读、幻读) 3. 隔离级别与并发性能的关系 4. MVCC的简要说明(根据引用[2]) 同时,生成相关问题。 注意:引用标识放在相关内容的末尾,例如:事务隔离级别定义了事务之间的可见性[^1]。 </think>### MySQL事务定义与隔离级别详解 #### 一、事务定义 事务数据库操作的最小工作单元,具备ACID特性: 1. **原子性**(Atomicity)事务内操作要么全部成功提交,要么全部失败回滚[^1] $$ \text{Commit或Rollback} \rightarrow \text{全成功/全失败} $$ 2. **一致性**(Consistency)事务使数据库从一个有效状态转换到另一个有效状态 3. **隔离性**(Isolation):并发事务相互隔离,互不干扰 4. **持久性**(Durability)事务提交后数据永久存储 #### 二、事务隔离级别 隔离级别决定并发事务间的可见性规则,级别越高并发性能越低[^1]: | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 实现机制 | 性能 | |-------------------|------|------------|------|------------------------|--------| | **读未提交** (READ UNCOMMITTED) | ✓ | ✓ | ✓ | 无锁 | 最高 | | **读已提交** (READ COMMITTED) | ✗ | ✓ | ✓ | 行锁 + MVCC[^2] | 较高 | | **可重复读** (REPEATABLE READ) | ✗ | ✗ | ✓ | MVCC快照[^2] | 中等 | | **串行化** (SERIALIZABLE) | ✗ | ✗ | ✗ | 表级锁[^3] | 最低 | ##### 关键问题说明: 1. **脏读**:读取到其他事务未提交的数据 2. **不可重复读**:同事务内两次读取结果不同(数据被修改) 3. **幻读**:同事务内两次查询返回不同行数(数据被新增/删除) 4. **MVCC机制**:通过版本链实现多版本并发控制(如下图)[^2] $$ \text{ReadView} + \text{Undo Log} \rightarrow \text{版本快照} $$ #### 三、隔离级别设置示例 ```sql -- 查看当前隔离级别 SELECT @@transaction_isolation; -- 设置会话级隔离级别 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 分布式事务需强制串行化[^4] SET GLOBAL transaction_isolation = 'SERIALIZABLE'; ``` #### 四、特殊场景说明 1. **分布式事务**:必须使用`SERIALIZABLE`级别保证全局一致性[^4] $$ \text{XA事务} \Rightarrow \text{所有参与者共进退} $$ 2. **InnoDB优化**:在`REPEATABLE READ`级别通过间隙锁(Gap Lock)解决幻读
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值