我们在一些 select 语句中使用 updlock 来确保只有一个连接可以读取数据。如果 SQL Server 可以从索引中获取所有数据,而另一个发出 updlock 的查询可以用另一个(非)聚集索引来满足,那么这似乎不起作用。
即使其他查询可以通过索引中的数据来满足,推荐的锁方法是什么?
例如,conn2 应该被阻塞直到 conn1 提交/回滚:
create database TestDB
go
use TestDB
go
create table LockTest(
LockTestID int not null identity(1,1) primary key,
Number int
)
create index IX_LockTest on LockTest(Number)
insert into LockTest(Number) values(1)
--Conn1
begin tran
select LockTestID from LockTest with(updlock) where LockTestID=1
--Conn2 -- The expectation here is, that this query waits untill Conn1 has committed
begin tran
select LockTestID from LockTest with(updlock) where Number=1
使用 holdlock 或 lock 可获得相同结果
正确,这是有记录的:
https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16#remarks
因此,如果您想使用锁提示来序列化这两个事务,您还需要一个索引提示,以便它们锁定相同的索引。
有可能,但多出的一列降低了这种可能性。唯一能确定的方法是同时使用索引提示。
如果您需要比基本语法和功能所提供的更多的控制,那么您可能需要应用程序锁。