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

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

事务的四大性质即ACID

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

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

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

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

 事物的隔离级别

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

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

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

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

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

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

下面首先谈一谈 可重复读

 从两个方面探究

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

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

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

2. 为什么会产生幻读:

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

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


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

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

MySQL 采用的是 可重复读。


转载请注明来源。

你可能感兴趣的:(数据库系列)