数据库事务的可串行化隔离技术解析
1 幻影问题与冲突实体化
在数据库事务处理中,会遇到一些特殊的并发问题,比如幻影问题。以值班医生的例子来说,如果步骤 3 中修改的行是步骤 1 返回的行之一,那么可以通过在步骤 1 中使用 SELECT FOR UPDATE 锁定行,使事务安全并避免写偏斜。但其他一些情况不同,它们检查是否存在符合某些搜索条件的行,而写入操作会添加符合相同条件的行。如果步骤 1 的查询没有返回任何行, SELECT FOR UPDATE 就无法锁定任何内容。
一个事务中的写入操作改变另一个事务搜索查询结果的这种效应,被称为幻影。快照隔离可以避免只读查询中的幻影,但在读写事务中,幻影可能导致特别棘手的写偏斜情况。
为了解决幻影问题,可以考虑冲突实体化的方法。以会议室预订为例,可以创建一个包含时间段和房间的表,表中的每一行对应特定时间段(如 15 分钟)内的特定房间。提前为所有可能的房间和时间段组合创建行,例如未来六个月的。当一个事务想要创建预订时,可以使用 SELECT FOR UPDATE 锁定该表中对应所需房间和时间段的行。获取锁后,就可以像以前一样检查是否有重叠的预订并插入新预订。需要注意的是,这个额外的表并不用于存储预订信息,它纯粹是一组锁,用于防止对同一房间和时间范围的预订被并发修改。
不过,冲突实体化也存在一些问题。确定如何实体化冲突可能很困难且容易出错,并且让并发控制机制渗透到应用程序数据模型中也不太好。因此,在没有其他替代方案时,冲突实体化应被视为最后的手段,在大多数情况下,可串行化隔离级别是更可取的。
超级会员免费看
订阅专栏 解锁全文
905

被折叠的 条评论
为什么被折叠?



