可序列化隔离模式可用于避免更新插入相等 id 时的竞争条件。因此,create table u(uid int primary key, name text);
如果我们运行两个相似的事务 T1 和 T2:
begin isolation level serializable;
select * from u where uid = 1;
Run Code Online (Sandbox Code Playgroud)
然后继续 T1 和 T2:
insert into u (uid, name) values (1, 'A');
Run Code Online (Sandbox Code Playgroud)
commit;
只有第一个成功,而另一个抛出序列化失败之后。
这是该模式的一个非常巧妙的功能,可以处理复杂交易中的独特密钥违规,而不是诉诸特定的“黑客” insert ... on conflict
。然而,即使 uid 不同,例如uid = 2
和uid = 3
,事务 T1 和 T2仍然无法提交。
怎么可能?据说他们创建了不同的谓词 SIReadlocks 并select
使用索引扫描。窍门在哪里?