为什么insert语句的独占锁不起作用

时间:2015-08-02 16:26:02

标签: sql-server tsql transactions

假设有两个事务按顺序执行:

交易1:

    BEGIN TRANSACTION 
         INSERT INTO my_table values(1, 'First')
    --not committed

交易2:

    BEGIN TRANSACTION 
          INSERT INTO my_table values(1, 'First')
    COMMIT TRANSACTION

为什么Transaction 2允许获取独占锁以完成查询,而不是暂停?

2 个答案:

答案 0 :(得分:2)

因为问题中示例中的排他锁可能会连续出现。

在层次结构中的较高对象(例如页面和对象)上仅使用IX个锁。

这不会阻止插入不同行的事务,因为IX锁是not mutually exclusive

使用下表示例

CREATE TABLE my_table
  (
     X INT,
     Y VARCHAR(100)
  ) 

并使用DBCC TRACEON(1200, -1, 3604)查看它返回的锁定信息

  

进程57获取对象的IX锁定:7:48719226:0(等级   bit2000000 ref1)结果:确定

     

进程57在PAGE上获取IX锁定:7:1:296(类bit2000000 ref0)   结果:好的

     

进程57获取RID上的X锁定:7:1:296:5(类bit2000000 ref0)   结果:好的

如果要创建一个禁用行锁的表(如下所示),则可能会遇到阻塞,因为X锁定是在页面级别进行的。

CREATE TABLE my_table
  (
     X INT,
     Y VARCHAR(100)
  ) 

  CREATE CLUSTERED INDEX IX on my_table(X) with(ALLOW_ROW_LOCKS = OFF)

答案 1 :(得分:0)

如果没有插入的记录很小,那么就会对行进行锁定。但是这个数字很大,那么SQL服务器可能会将行级锁定升级到表级锁定。