数据库系列之——事务隔离的可重复读

本文介绍了数据库事务的ACID特性,并详细解析了事务的四种隔离级别,重点讨论了可重复读隔离级别如何避免不可重复读以及为何会产生幻读的问题。SQL Server和Oracle使用读已提交,而MySQL则选择可重复读作为默认隔离级别。

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

简介:事务是一条或多条数据库操作的集合,在事务中的操作,要么都执行修改,要么都不执行。

事务的四大性质即ACID

A(atomicity)原子性:一个事务的执行被视为一个不可分割的最小单元。事务里面的操作,要么全部成功执行,要么全部失败回滚,不可以只执行其中的一部分。

C(consistency)一致性:一个事务的执行不应该破坏数据库的完整性约束。

I(isolation)隔离性:事务之间相互独立,互不干挠。

D(durability)持久性:事务提交之后,需要将提交的事务持久化到磁盘。即使系统崩溃,提交的数据也不应该丢失。

 事物的隔离级别

事物的隔离级别主要分为四种,即

Read uncommitted(读未提交):事务中的修改,即使没有提交,在其他事务也都是可见的。结果:产生脏读

Read committed(读已提交):一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫做不可重复读,因为在一个事物中执行多次相同的查询,可能会得到不一样的结果。因为在这多次读之间可能有其他事务更改这个数据,每次读到的数据都是已经提交的。结果:产生不可重复读

Repeatable read(可重复读):解决了脏读,也保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读的问题,指的是当某个事务在读取某个范围内的记录时,另外一个事务也在该范围内插入了新的记录或删除了原有的记录,当之前的事务再次读取该范围内的记录时,好像产生幻觉。结果:产生幻读

Serializable(可串行化):它通过强制事务串行执行,避免了前面说的幻读的问题,但由于读取的每行数据都加锁,会导致大量的锁征用问题,因此性能也最差。

隔离级别产生脏读产生不可重复读产生幻读
读未提交
读已提交×
可重复读××
串行化×××

下面首先谈一谈 可重复读

 从两个方面探究

1. 如何避免了不可重复读:

首先,不可重复读是因为在一个事物中执行多次相同的查询,可能会得到不一样的结果。因为在这多次读之间可能有其他事务更改这个数据,每次读到的数据都是已经提交的。

那么可重复读是如何避免了这个问题呢?原来是因为事物在执行查询时,对检索的数据(范围性)都加了行锁(LOCK),这样其他事物就无法对这些加了锁的数据进行更改,自然避免了同一事物多次查询数据不一致的问题。

2. 为什么会产生幻读:

指的是当某个事务在读取某个范围内的记录时,另外一个事务也在该范围内插入了新的记录,当之前的事务再次读取该范围内的记录时,会产生幻行。

上面谈到如何避免不可重复读,是因为对检索到的数据加了锁,但是并没有阻止别的事物在这些数据行中间插入新的数据行,导致同一事物多次查询时,突然发现多出来一行或几行数据(幻行)。这就是所谓的幻读。


当下,热门的几大数据库如

SQL Server、Oracle 都采用的是第二隔离级别:读已提交。

MySQL 采用的是 可重复读。


转载请注明来源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值