【发布时间】:2017-12-01 22:35:06
【问题描述】:
考虑这个表和两个并发查询:
create table BLARG (a int not null unique);
连接 #1:
set transaction isolation level snapshot;
begin transaction;
if exists (select 1 from BLARG with (serializable) where a=1) print 'DIE!';
连接 #2:
set transaction isolation level snapshot;
begin transaction;
insert into BLARG values (2); -- Blocked!
为什么插入 a=2 会阻止寻找 a=1 的可序列化读取?
在快照隔离中,还有其他方法可以防止插入到表中吗?
...
如果我过于笼统或没有提出完全正确的问题,这是我的(稍微不那么笼统但仍然笼统)的场景:
表 [Parts] 和 [Completed] 各有“Txid”列
对于任何 Txid,可以在创建 [Completed] 记录之前完成对 [Parts] 的插入,由 [Parts] 插入触发器按照“如果存在(从 Completed where Txid=... ) 扔”。
插入到 [Completed] 会导致 [Parts] 表被汇总,结果转到其他地方
所有事务都以快照隔离开始
如果 2 个事务开始,然后一个插入 [Completed],一个插入 [Parts],写入偏差将使 [Completed] 触发器错过并发事务中发生的插入 [Parts]。
但是 [Completed] 是一个非常繁忙的表,如果要阻止所有插入,则宁愿不使用 Serializable 隔离,而只有具有匹配 Txid 的插入是有问题的。
有没有更优化的解决方案?
【问题讨论】:
标签: sql-server