在事务(例如T1)中使用HOLDLOCK或UPDLOCK似乎不会阻止来自另一个事务(例如T2)的读取访问。据我了解,在T1完成之前,HOLDLOCK将阻止T2更新/删除。 UPDLOCK将阻止T2更新/删除/插入。在这两个T2中,将对这些记录具有读取访问权限。但是,同时使用这两个(例如:HOLDLOCK, UPDLOCK)也会阻止T2进行读取访问。当我们同时使用它们时,会发生什么?感谢您的见解更新:那不是我所看到的:例如:在查询1中:begin transelect * from tblTest WITH (UPDLOCK, HOLDLOCK)WAITFOR DELAY '00:00:10'commit tran在查询2中:select * from tblTest在查询1完成之前,查询2不会产生结果。 最佳答案 UPDLOCK影响锁的类型。这意味着对于SELECT语句,将采用U锁,而不是S锁。在默认的读取提交级别,它们将在读取数据后立即释放。以上适用于行锁和页锁。对于表级锁定BOL状态 如果UPDLOCK与TABLOCK结合使用,或者采用了表级锁 由于其他原因,将使用排他(X)锁。HOLDLOCK意味着您将获得可序列化的隔离语义,以便在事务结束之前不会释放这些锁,并且至少您查询所覆盖的整个范围都将被锁定以防止插入幻像。U锁与其他S锁兼容,但与其他U锁不兼容(请参阅Lock compatibility matrix),因此,如果锁是在行或页面级别取出的,除非其他读者也使用提示。如果由于UPDLOCK而取消了对象级别的X锁,则读取器将被阻止,试图在表上获取UPDLOCK锁。在您的示例查询中,尝试查看IS,而第二个查询被阻止,以查看两个事务拥有/正在等待的锁。对于您问题中的查询SELECT *FROM tblTest WITH (UPDLOCK, HOLDLOCK)如果查询计划显示对堆的扫描,则将始终在对象上获得sys.dm_tran_locks锁。如果是索引扫描,则取决于所使用的锁定粒度(通常在获取at least 5,000较低级别的锁之后尝试将锁升级为表级)。
07-24 09:25