【问题标题】:SQL Serializable, but avoiding insert locks that wouldn't conflictSQL 可序列化,但避免插入不会冲突的锁
【发布时间】: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


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 2011-07-02
      • 1970-01-01
      • 2010-10-02
      相关资源
      最近更新 更多