事务的隔离级别

本文深入探讨了数据库中的四种事务隔离级别:读未提交、读已提交、可重复读和串行化,分析了各自的特点及存在的问题,如脏读、不可重复读和幻读。针对这些问题,提出了相应的解决方案,如加锁机制和MVCC。同时,解释了这些隔离级别如何影响并发事务的执行,以及在实际应用中的选择策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以MYSQL数据库来分析四种隔离级别

-- 事务查询sql
select @@tx_isolation;

基础概念

更新丢失(Lost update)

如果多个线程操作,基于同一个查询结构对表中的记录进行修改,那么后修改的记录将会覆盖前面修改的记录,前面的修改就丢失掉了,这就叫做更新丢失。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。
第1类丢失更新:事务A撤销时,把已经提交的事务B的更新数据覆盖了。
第2类丢失更新:事务A覆盖事务B已经提交的数据,造成事务B所做的操作丢失。
解决方法:对行加锁,只允许并发一个更新事务。

脏读(Dirty Reads)

脏读: A事务读取B事务尚未提交的数据并在此基础上操作,而B事务执行回滚,那么A读取到的数据就是脏数据。

解决办法:如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可以避免该问题。

不可重复读(Non-repeatable Reads)

一个事务对同一行数据重复读取两次,但是却得到了不同的结果。事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。
解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。

幻读(Phantom Reads)

指两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中。一般情况下,幻象读应该正是我们所需要的。但有时候却不是,如果打开的游标,在对游标进行操作时,并不希望新增的记录加到游标命中的数据集中来。隔离级别为 游标稳定性 的,可以阻止幻象读。例如:目前工资为1000的员工有10人。那么事务1中读取所有工资为1000的员工,得到了10条记录;这时事务2向员工表插入了一条员工记录,工资也为1000;那么事务1再次读取所有工资为1000的员工共读取到了11条记录。
解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题。

读未提交(Read uncommitted)

如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据,该隔离级别可以通过“排他写锁”,但是不排斥读线程实现。这样就避免了更新丢失,却可能出现脏读,也就是说事务B读取到了事务A未提交的数据

解决了更新丢失,但还是可能会出现脏读
实现原理:

读已提交(Read committed)

如果是一个读事务(线程),则允许其他事务读写,如果是写事务将会禁止其他事务访问该行数据,该隔离级别避免了脏读,但是可能出现不可重复读。事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

解决了更新丢失和脏读问题

可重复读(Repeatable read)(默认)

可重复读取是指在一个事务内,多次读同一个数据,在这个事务还没结束时,其他事务不能访问该数据(包括了读写),这样就可以在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务(包括了读写),这样避免了不可重复读和脏读,但是有时可能会出现幻读。(读取数据的事务)可以通过“共享读镜”和“排他写锁”实现。

解决了更新丢失、脏读、不可重复读、但是还会出现幻读

串行化(Serializable)

提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行,如果仅仅通过“行级锁”是无法实现序列化的,必须通过其他机制保证新插入的数据不会被执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也是最高的,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读

解决了更新丢失、脏读、不可重复读、幻读(虚读)

原理:
事务本身是基于mvcc控制的,mvcc的机制就是基于快照的形式。所以各个隔离级别的区别在于创建快照的机制不同。
读未提交: 没有视图的概念,直接返回最新值。
读已提交: 在sql语句执行时候生成的快照,在一个事务中,总是生成最新的快照,因此可以读到最新的数据。
可重复读: 事务开启的时候创建快照,在事务的执行过程中用的都是同一个快照不会改变,所以在同一个视图中是不会读取到其他事务进行的操作。
串行化: sql一条条执行,不存在事务并发的情况,也就不存在读取不一致的发生。
详见:https://blog.youkuaiyun.com/qq_38571987/article/details/118524345

锁:https://zhuanlan.zhihu.com/p/118658549

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆烂的小趴菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值