【发布时间】:2011-10-21 00:12:53
【问题描述】:
在研究Table Hints的使用时,我遇到了这两个问题:
两个问题的答案都说当使用(UPDLOCK, HOLDLOCK) 时,其他进程将无法读取该表上的数据,但我没有看到这一点。为了测试,我创建了一个表并启动了两个 SSMS 窗口。在第一个窗口中,我运行了一个使用各种表提示从表中选择的事务。在事务运行时,我从第二个窗口运行各种语句以查看哪些语句会被阻止。
测试表:
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](50) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
从 SSMS 窗口 1:
BEGIN TRANSACTION
SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'
COMMIT TRANSACTION
从 SSMS 窗口 2(运行以下之一):
SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'
不同的表提示对在 Window 2 中运行的语句的影响:
(UPDLOCK) (HOLDLOCK) (UPDLOCK, HOLDLOCK) (TABLOCKX)
---------------------------------------------------------------------------
SELECT not blocked not blocked not blocked blocked
INSERT not blocked blocked blocked blocked
UPDATE blocked blocked blocked blocked
DELETE blocked blocked blocked blocked
我是否误解了这些问题中给出的答案,或者在我的测试中犯了错误?如果不是,你为什么要单独使用(UPDLOCK, HOLDLOCK) 而不是(HOLDLOCK)?
进一步解释我要完成的工作:
我想从表中选择行并防止在处理该表时修改该表中的数据。我没有修改该数据,并希望允许进行读取。
This answer 明确表示(UPDLOCK, HOLDLOCK) 将阻止读取(不是我想要的)。 this answer 上的 cmets 暗示是 HOLDLOCK 阻止读取。为了尝试更好地理解表格提示的效果并查看单独 UPDLOCK 是否可以满足我的要求,我进行了上述实验并得到了与这些答案相矛盾的结果。
目前,我认为(HOLDLOCK) 是我应该使用的,但我担心我可能犯了错误或忽略了将来会回来咬我的东西,因此提出了这个问题。
【问题讨论】:
标签: sql-server tsql sql-server-2008 concurrency locking