我正在处理一个糟糕的 View ,它在内部将许多 许多 表连接在一起,其中一些是同一张表。
我想知道,当一个表被连接到自身时,如果 NOLOCK
提示是在一个连接上而不是另一个连接上,它是如何解释的? NOLOCK
是否仍然对表有效,或者如果 NOLOCK
未包含在同一表的连接之一中,表是否被完全锁定?
例如(这是伪代码,假设存在有效的 JOIN ON
条件):
SELECT *
FROM Table1 t1 (NOLOCK)
JOIN Table2 t2 (NOLOCK)
JOIN Table2_Table2 tt (NOLOCK)
JOIN Table2 t22 (NOLOCK)
JOIN Table1 t11
Table1
是否被锁定或保持NOLOCK
状态?
最佳答案
是的,它确实被最后一次 Table1 t11
调用锁定了。每个表锁定提示都应用于特定引用。如果您仅将其应用于仅用于该引用的表引用之一,则其他表将具有自己的单独锁定设置。您可以使用 BEGIN TRANSACTION
对此进行测试并执行两个不同的查询。
查询1(锁表)
故意注释掉 COMMIT TRANSACTION
BEGIN TRANSACTION
SELECT *
FROM Table1 WITH (TABLOCK)
-- COMMIT TRANSACTION
因为 COMMIT TRANSACTION
被注释掉了,所以事务没有关闭并且仍然持有锁。当运行第二个查询时,第一个锁仍将应用于第一个查询的表。
查询 2(此查询将挂起,因为第一个锁将阻塞 Table1 t11
)
BEGIN TRANSACTION
SELECT *
FROM Table1 t1 (NOLOCK)
JOIN Table2 t2 (NOLOCK)
JOIN Table2_Table2 tt (NOLOCK)
JOIN Table2 t22 (NOLOCK)
JOIN Table1 t11
COMMIT TRANSACTION
关于sql-server - 在连接到自身的表上使用 NOLOCK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25515547/