SQL 服务器:VIEW with NO LOCK 但调用时没有 NO LOCK
SQL Server: VIEW with NO LOCK but called without NO LOCK
我在 Microsoft SQL Server 2016 上,我有以下引用视图的(简化的)查询:
SELECT Column1
FROM dbo.myView
视图如下所示:
CREATE VIEW dbo.myView
AS
SELECT Column1
FROM dbo.SomeOtherTable WITH (NOLOCK)
我现在的问题是: 外 SELECT 确实 不 使用 NOLOCK table 提示暗示 VIEW 内的 NOLOCK 无关紧要?或者在执行外部 SELECT 时 NOLOCK 是否仍然相关?
我的问题的更大背景是我有一个案例,我正在分析服务器上的阻塞情况。我发现了一个查询,例如上面描述的 SELECT:A SELECT query was using a VIEW。 VIEW 使用了 NOLOCK table 提示,但外部 SELECT 没有。尽管如此,该查询仍然是一个障碍,我正在尝试找出造成这种情况的原因。
我已经做了一些研究,我能找到的唯一确认是人们想知道 NOLOCK
是否向下传播到内部 tables 的问题。
这很容易测试。首先,在沙盒环境中,运行 如下:
CREATE TABLE dbo.MyTable (ID int);
GO
CREATE VIEW dbo.MyView AS
SELECT ID
FROM dbo.MyTable WITH (NOLOCK);
GO
CREATE VIEW dbo.MyView2 AS
SELECT ID
FROM dbo.MyTable;
GO
BEGIN TRANSACTION Test;
INSERT INTO dbo.MyTable
VALUES(1);
注意我没有COMMIT
交易。现在在一个新的 window、运行 SELECT * FROM dbo.MyView;
中。注意它 returns 结果。如果你也尝试 SELECT * FROM dbo.MyView2 WITH (NOLOCK);
你也会得到结果。但是,请尝试 SELECT * FROM dbo.MyView2;
,查询将“挂起”。
然后您可以通过返回原始查询 window 和 运行 执行以下操作来“清理”:
COMMIT;
GO
DROP VIEW dbo.MyView2;
DROP VIEW dbo.MyView;
DROP TABLE dbo.MyTable;
当然,真正的问题是,你需要 NOLOCK
,但这不是这个的问题是关于。
我在 Microsoft SQL Server 2016 上,我有以下引用视图的(简化的)查询:
SELECT Column1
FROM dbo.myView
视图如下所示:
CREATE VIEW dbo.myView
AS
SELECT Column1
FROM dbo.SomeOtherTable WITH (NOLOCK)
我现在的问题是: 外 SELECT 确实 不 使用 NOLOCK table 提示暗示 VIEW 内的 NOLOCK 无关紧要?或者在执行外部 SELECT 时 NOLOCK 是否仍然相关?
我的问题的更大背景是我有一个案例,我正在分析服务器上的阻塞情况。我发现了一个查询,例如上面描述的 SELECT:A SELECT query was using a VIEW。 VIEW 使用了 NOLOCK table 提示,但外部 SELECT 没有。尽管如此,该查询仍然是一个障碍,我正在尝试找出造成这种情况的原因。
我已经做了一些研究,我能找到的唯一确认是人们想知道 NOLOCK
是否向下传播到内部 tables 的问题。
这很容易测试。首先,在沙盒环境中,运行 如下:
CREATE TABLE dbo.MyTable (ID int);
GO
CREATE VIEW dbo.MyView AS
SELECT ID
FROM dbo.MyTable WITH (NOLOCK);
GO
CREATE VIEW dbo.MyView2 AS
SELECT ID
FROM dbo.MyTable;
GO
BEGIN TRANSACTION Test;
INSERT INTO dbo.MyTable
VALUES(1);
注意我没有COMMIT
交易。现在在一个新的 window、运行 SELECT * FROM dbo.MyView;
中。注意它 returns 结果。如果你也尝试 SELECT * FROM dbo.MyView2 WITH (NOLOCK);
你也会得到结果。但是,请尝试 SELECT * FROM dbo.MyView2;
,查询将“挂起”。
然后您可以通过返回原始查询 window 和 运行 执行以下操作来“清理”:
COMMIT;
GO
DROP VIEW dbo.MyView2;
DROP VIEW dbo.MyView;
DROP TABLE dbo.MyTable;
当然,真正的问题是,你需要 NOLOCK
,但这不是这个的问题是关于。