【问题标题】:Insert and delete in a transaction always block the rows?在事务中插入和删除总是阻塞行?
【发布时间】:2019-10-12 06:30:09
【问题描述】:

我有这张桌子:

TableAB
{
    IDA;
    IDB;
}

而且我想确保始终拥有 (ID1, ID2) 和 (ID2, ID1) 对。所以我试图将它用于脚本:

插入:

begin tran
insert into tablaAB (IDTablaA, IDTablaB) VALUES(1,2);
insert into tablaAB (IDTablaA, IDTablaB) VALUES(2,1);
commit

删除:

begin tran
delete tablaAB where IDTablaA = 1 and IDTablaB = 2
delete tablaAB where IDTablaA = 2 and IDTablaB = 1;
commit

我正在使用 Microsoft Management Studio 的两个实例来运行这两个查询,并且在大多数情况下,它可以正常工作,我得到两行或其中任何一行。但有时,我只得到其中一个。

步骤如下:

  • 运行查询以删除 (1,2)。
  • 运行查询以添加 (1,2)。

在大多数情况下,它是阻塞的,直到删除两行的事务完成,但在某些情况下,它可以传递到下一行,插入第二行。如果发生这种情况,那么我没有一致性数据。

但我不知道是因为我在测试中犯了一些错误,还是在同样罕见的情况下,第一个查询没有像我预期的那样被阻止。

如果第一次删除完成,真的在所有情况下第一次插入都应该被阻塞吗?

桌子是空的。因此,当我尝试删除时,似乎该行被阻止并且不允许插入该行,但我不知道是否真的会出现一些罕见的行未被阻止的情况。

谢谢。

【问题讨论】:

    标签: sql-server transactions


    【解决方案1】:
    But I don't know if it is because I make some mistakes in the test or in same rare cases the first query is not blocked as I expect.
    
    Really in all cases the first insert should be block if the first delete is done?
    

    您似乎正在使用 READ COMMITTED 隔离级别运行。在这种情况下,当没有行符合条件时,DELETE 会话不会持有任何锁,因此 INSERT 会话可以继续插入行。这成为一种竞争条件,您最终可能会得到零、一或两行。考虑这个产生一行的序列:

    --session 1:
    begin tran;
    delete TableAB where IDTablaA = 1 and IDTablaB = 2;
    --no row deleted, no lock held
    
    --session 2:
    begin tran
    insert into TableAB (IDTablaA, IDTablaB) VALUES(1,2);
    --row inserted, lock held
    insert into TableAB (IDTablaA, IDTablaB) VALUES(2,1);
    --row inserted, lock held
    commit;
    -- inserts committed and locks released
    
    --session 1:
    delete TableAB where IDTablaA = 2 and IDTablaB = 1;
    --row deleted, lock held
    commit;
    --deleted committed, lock released
    

    如果您改为使用SERIALIZABLE 隔离级别,DELETE 语句将持有锁(在这种情况下,由于没有索引,表锁)并阻止插入会话。一个限制较少的键范围锁将与用于定位要删除的行的列上的索引一起持有。

    请注意,SERIALIZABLE 是否比限制较少的隔离级别更容易出现死锁。

    【讨论】:

      猜你喜欢
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 1970-01-01
      相关资源
      最近更新 更多