3

事务中的脏读,不可重复读,幻影读:Isolation of databases

 3 years ago
source link: https://zhuanlan.zhihu.com/p/254453080
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

事务中的脏读,不可重复读,幻影读:Isolation of databases

一个人NB的不是标签

ACID(Atomic, Consistent, Isolation, Duration)是数据库里面经常听到的一个词。

那么脏读(dirty read),不可重复读(no-repeatable read), 幻影读(phantom read)呢?

在几次debug的过程中,我就遇到了由此引发的问题,于是写这篇文章记录这些概念和它们会造成的问题。

Isolation

数据库会同时被多个client连接,每个client有可能生成一个事务(transaction),那么数据库如何保证它们不会互相影响呢?

为了解决这个问题,SQL标准定义了四个隔离(isolation)等级,其中最严格的等级定义为多个transaction发生的时候不论它们怎么执行,效果都一个接着一个执行。而另外的三个等级的定义则是对应某一类型的问题。这三个问题

  1. 脏读(dirty read)
  2. 不可重复读(non-repeatable read)
  3. 幻影读(phantom read)

而对应的三个等级是:

  1. read uncommitted
  2. read committed
  3. repeatable read

接下来我们就用例子来说明每个问题是什么样子的。网上已经有许多文章讲述它们,但是它们都缺少相应的可以自己动手重现的例子,这里的例子稍加修改就可以在MySQL 8.x重现。

脏读 Dirty read

脏读是指读到了别人没有commit的data。一个transaction虽然往数据库写了data,但是它还是可以反悔的,选择rollback。而脏读就是别的transaction还没有commit,就把数据读取了,结果别的transaction反悔了(rollback)。比如下面的两个transactions:

Transaction A 读到了1, dirty,可实际上1, dirty根本没有存在数据库里面,因为transaction B rollback了。

当我们将transaction A从read uncommitted改为read committed, 那么1, dirty就不会显示在transaction A。

不可重复读 non-repeatable read

不可重复读,就是当对同一行数据,读两遍得到的结果不一样。比如下面的例子

transaction A 第一次读取数据,取到了1, dirty,但是再读一遍的时候,变成了1, clean。这是为什么呢?因为transaction B 在A在开始读第二次的时候,将数据篡改并commit了!相同的记录重复读取结果不一样,也就是不可重复读。

当我们把transaction A从read committed改为repeatable read, 那么第二次select得到还是1, dirty,而不是1, clean。

幻影读 photom read

幻影读,指当两次搜索相同条件的数据时候,返回的数据不一样,比如行数不对了。如

transaction A 在第一次搜索的时候,返回了一行数据,但是第二次搜索的时候结果返回了两行数据。感觉好像出现了幻影!当我们将transaction A从repeatable read改为serializable,那么第二次select返回就是1, clean,而不是1, clean 和2, clean。

不出现脏读对应的isolation等级就是read commited。

不出现non-repeatable对应的等级就是repeatable read。

那么对应不出现photom read呢?在MySQL里面是 serializable, 在PostgresSQL里面repeatable read就不会出现幻影读了。具体数据库是如何实现各个等级,请看下文分解~

References:

Documentation: 9.5: Transaction Isolation

Understanding MySQL Isolation levels: repeatable-read | Official Pythian® Blog


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK