SQL Serializable,但避免不会发生冲突的插入锁

时间:2017-12-01 22:35:06

标签: sql-server

考虑这个表和两个并发查询:

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!

为什么插入= 2 会阻止序列化读取,以寻找a = 1

在快照隔离中,是否有另一种阻止插入表的方法?

...

如果我过度概括或者没有问一个准确正确的问题,这里是我的(稍微不那么概括但仍然概括)的情景:

表[部件]和[已完成]每个都有列“Txid”

对于任何Txid,可以完成对[Parts]的插入,直到创建[Completed]记录,由[Parts]插入触发器强制执行“if exists”(从Completed中选择1,其中Txid = ...扔掉。“

插入[已完成]会导致[部件]表汇总,结果将转到其他地方

所有交易均以快照隔离

开始

如果2个事务开始,则一个插入[Completed],一个插入[Parts],写入偏差会使[Completed]触发器错过并发事务中发生的[Parts]插入。

但是[Completed]是一个非常繁忙的表,如果它只是一个带有匹配Txid的插入有问题,它会阻止所有插入,宁可不使用Serializable隔离。

是否有更优化的解决方案?

1 个答案:

答案 0 :(得分:0)

Why insert TSQL statement block when transaction isolation level for another transaction is serializable with non-conflicting filter?

(终于在另一个堆栈问题上找到了它,grr)

答案:最初的例子不起作用,因为表格是空的。