8

更新丢失、写偏、幻读:数据库事务从快照隔离到可序列化(二)

 3 years ago
source link: https://qcngt.com/2020/08/23/snapshot-2.html
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.

青菜年糕汤

一周一篇,一期一会。以文会友,以友辅仁。

2020年8月23日

更新丢失、写偏、幻读:数据库事务从快照隔离到可序列化(二)

作者:青菜年糕汤

更新丢失、写偏、幻读:数据库事务从快照隔离到可序列化(,二,番外

我发现,很多时候,人类学习(其实机器学习更是如此)新概念的难度来自于作为参考的案例不多。

为了讲清楚快照隔离(snapshot ioslation)相对于可序列化(serializable)可能产生的问题,我想多举几个例子,再针对它们的相同和不同之处进行讨论。所以这一篇全都是例子,等下一篇再分析。

出自卡内基梅隆大学高级数据库系统(15-721 Advanced Database Systems)课程对写偏(write skew)的解释

有四个棋子分别为黑、黑、白、白。

事务甲:把所有白色棋子变成黑色。
事务乙:把所有黑色棋子变成白色。

每个事务要做的事情都是:第一步,查找所有白(黑)色棋子;第二步,把找到的棋子改成黑(白)色。

如果是可序列化隔离级别,可以假装两个事务先后发生,最后结果要不是全黑,要不是全白。

但在快照隔离下,如果两个事务都是在对方做第二步之前就做了自己的第一步,事务甲会把那两个原先黑的改成白的,事务乙把那两个原先白的改成黑的,最后变成了白、白、黑、黑。这是在两个事务先后时不可能出现的情况。

出自《数据密集型应用系统设计》。

值班系统记录了每个医生分别是否在值班。为了保证至少有一位医生在值班,当一个医生要下班时,会运行这样一个事务:

查找有多少医生正在值班,如果数量大于1,可以把这个医生改为下班,否则不行。

假如现在有两个医生正在值班,她们近乎同时想要下班。

快照隔离下,两个医生分别使用一个事务,两个事务有可能同时查找有多少医生正在值班,等它们都得到了结果(结果都是2)之后,才分别改为下班。这样,值班的医生就一个都没有了。

而在可序列化下两个事务先后进行就不会出现这样的问题。

也出自《数据密集型应用系统设计》。

一个网站的用户管理系统,规定每个用户都要用独一无二的用户名。

假设这个表的主键(primary key)就是用户名。当有一个用户要创建账号时,会有个事务先查找是否有这个用户名的记录,如果没有,就可以创建。

跟例2一样,在快照隔离下,可能两个同时发生的事务想创建相同的用户名,它们查找时都发现这个账号不存在,便重复为这个用户名创建了账号。后果可能是一个账号的信息覆盖了另一个。

我在例3的基础上稍加创作。

因为疫情,霍格沃茨今年将入学的方式改成了使用门钥匙。但为了有足够的时间做核酸检测和隔离,要求每个学生入学时间至少相差60秒。学生可以在魔法部门钥匙办公室的系统申请入学时间,时间可以精确到比纳秒还小。

为了实现这个需求,魔法部使用了一个有序的(而不是基于哈希的)数据库,在其中用入学时间作为主键。

每当有学生申请一个入学时间,就有个事务会范围搜索(range query)在它前后各60秒的范围内是否有其它人入学,如果没有才能成功创建。

某对调皮的双胞胎不想分开入学,就几乎同时申请了几乎同时的入学时间。在快照隔离下,两个事务有可能会都没看到对方插入的记录,从而让两条记录都创建成功。

例子终于讲完了,下面请移步至第三篇看我对这四个例子的分析。

WeChat QR code

友情链接:Levy's Ink
Copyright © 2020 青菜年糕汤 保留所有权利。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK