昨天在给小伙伴讲解数据库里事务 (Transaction) 的概念,以及他的 ACID (Atomicity, Consistency, Isolation, Durability) 属性,其中讲到 Isolation 里不同的 Isolation Level (隔离等级) 时我用了一个鹅卵石的比方。

    假设我们有一袋夹杂了黑白两色的鹅卵石,又假设我们要跑两条事务,其中一条事务是把所有的白色鹅卵石变成黑色,另一条事务是把所有的黑色鹅卵石变成白色。

    如果这两条事务都按照顺序先后执行的话,那最终无非有两种可能,要么所有石头都变成白色,要么全变成黑色。
    CleanShot 2022-02-12 at 10.01.46.png
    这个行为对应的就是 Isolation 中最高的等级,serializable level。顾名思义,设置了这个等级,两条事务执行完后所展现的行为就像是顺序执行一样,既然是顺序执行,互相之间就没有干扰,自然就达到了最高的 Isolation 等级

    但为了提速,我们也可以让两条事务并行执行。但并行执行的事务就会造成互相干扰,而数据库引入了一种巧妙的方法来尽可能降低因此带来的副作用 (side-effect),叫做快照 (snapshot)。还是拿前面的鹅卵石举例,两条事务在执行前,分别会对当前状态做了一个快照。在时机恰好的情况下,第一条白变黑的事务,发现了还有另外一半白色的石头,所以他接下来做的操作是把另一半石头变成黑色的,而另外一条黑变白的事务,做的事情则恰恰相反。这两条事务在各自执行的时候,都以为能把对方的颜色翻过来,实现颜色的大一统,结果做完后却发现,咦,怎么黑白颠倒了?
    CleanShot 2022-02-12 at 13.14.59.png
    如果是顺序执行的情况下,最后的结果一定是非黑即白的,但在用 Snapshot 并行执行下,就可能出现第三种结果,黑白颠倒。这也就是 Isolation 级别中比 serializable level 低一级的,叫做 snapshot level。为什么说是低一级呢,因为黑白颠倒是一种异常 (anomaly)。为什么这是一种异常呢,因为如果 Isolation 做到完美,行为就该 100% 和顺序执行一样,而顺序执行是不会出现黑白颠倒这种现象的。

    我相信这个比方比所有教材上解释 serializable 和 snapshot 这两个 Isolation level 区别的都讲的清楚和便于记忆。当然这个比方不是我想出来的,而是来自于 Jim Gray,图灵奖获得者,现代关系型数据库系统的奠基人,我只是稍微做了一个修改,原话里用的是 marble,翻译过来是弹珠而不是鹅卵石。

    大师就是大师,所以 Bytebase 早期版本的登录页也有向先贤的致敬

    CleanShot 2022-02-12 at 16.33.04@2x.png

    Simple systems work and complex don’t.

    另外 Isolation Level 还能引申出另一个有趣的话题,下次有机会再写。


    故事的英文原文见 Serializable vs. Snapshot Isolation Level