SQL Server 的事务和锁(二)-Range S-S锁
在这篇随笔中,我们的主要关注点在 Key-Range Lock。Key-Range Lock有 S-S、S-U、I-N、X-X几种情况。我们一个一个来说,力求明白。遗憾的是,这里可能会比较冗长,那么死锁分析只好依次顺延了。
Range S-S锁的获取规则
MSDN 对 Range 锁的规则有部分描述,但是言简意赅,以下我们会将各种情况分解开来,理清MSDN中涉及的或者未涉及的规则,这些规则适用于SQL Server 2000/2005/2008/2008 R2。关于MSDN的描述,请参见:http://technet.microsoft.com/zh-cn/library/ms191272(en-us,SQL.110).aspx。
在描述规则之前需要声明的是,我们的聚集索引就建立在 WHERE 字句之上,这很重要,否则是不会获得 Range 锁的,也就达不到 SERIALIZABLE 的要求了;另外,为了讨论简便,以下的 SQL 全部省略 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 的声明。
我们假设有以下的表:
01 CREATE TABLE [dbo].[MyTable](
02 [id] [int] IDENTITY(1,1) NOT NULL,
03 [index_column] [int] NOT NULL,
04 [data] [int] NOT NULL,
05 CONSTRAINT [PK_MyTable] PRIMARY KEY NONCLUSTERED
06 (
07 [id] ASC
08 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
09 ) ON [PRIMARY]
10
11 CREATE UNIQUE CLUSTERED INDEX [IX_MyTable] ON [dbo].[MyTable]
12 (
13 [index_column] ASC
14 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
并假设我们有如下的数据:
01 INSERT INTO [MyTable] ([index_column],[data]) VALUES (1, 1)
02 INSERT INTO [MyTable] ([index_column],[data]) VALUES (2, 2)
03 INSERT INTO [MyTable] ([index_column],[data]) VALUES (3, 3)
04 INSERT INTO [MyTable] ([index_column],[data]) VALUES (4, 4)
05 INSERT INTO [MyTable] ([index_column],[data]) VALUES (5, 5)
06 INSERT INTO [MyTable] ([index_column],[data]) VALUES (15, 6)
07 INSERT INTO [MyTable] ([index_column],[data]) VALUES (16, 7)
08 INSERT INTO [MyTable] ([index_column],[data]) VALUES (18, 8)
09 INSERT INTO [MyTable] ([index_column],[data]) VALUES (25, 9)
10 INSERT INTO [MyTable] ([index_column],[data]) VALUES (30, 10)
那么这张表看起来应该是这样的(我另外还将Index的Hash值以及row所在的数据页Dump出来了,以便咱们做实验)。
id | index_column | data | index hash | row page |
1 | 1 | 1 | (8194443284a0) | 78 |
2 | 2 | 2 | (61a06abd401c) | 78 |
3 | 3 |