日期:2014-05-16  浏览次数:20513 次

序列化隔离级别Key-Range锁定的真实键范围

 

大家都知道在序列化隔离级别中引入了键范围锁定。键范围锁可防止其他事务插入其键值位于可序列化事务读取的键值范围内的新行,从而确保满足此要求。但是对于锁定的范围真的清楚吗?

 

前几天看到有人对于锁范围的疑问,发现锁定的数据比想象的要多。

 

下面我们看个例子:

---create tableand insert test data

CREATE TABLE TEST(C1INTprimary key,C2VARCHAR(20))

INSERT INTO testVALUES(1,'TEST'),(2,'TEST'),(3,'EST')

--第一个窗口查询执行

 

 SET TRANSACTIONISOLATIONLEVELSERIALIZABLE

  BEGIN TRAN

  SELECT * FROM test WHERE C1 BETWEEN 1 AND 3

--第二个窗口查询执行

INSERT INTO testVALUES(100,'TEST')

 

按照一般的理解,Rang锁应该会锁定1-3的数据,不允许对其中的数据进行任何修改,所以插入100应该是可以正常执行的。 但是插入100的进程一直被Block无法执行。

 

通过sys.dm_tran_locksresource_description字段我们可以看到“ffffffffffff”,也就是说它的键范围锁是123到无穷大,而并不少单纯的123。这个跟我们平常所理解的Rang范围有冲突了。

 

查看MSDN有一个                              注意