Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 更新内部事务时nolock提示不起作用_Sql_Sql Server - Fatal编程技术网

Sql 更新内部事务时nolock提示不起作用

Sql 更新内部事务时nolock提示不起作用,sql,sql-server,Sql,Sql Server,名为Users的表在事务中与其他批一起更新,当过程正在进行时,Users表被锁定,即使使用nolockhint,我也无法从中选择 BEGIN TRY BEGIN TRANSACTION ---------------------------Apply Users Changes----------------------------- ALTER TABLE Security.Users NOCHECK CONSTRAINT ALL; ...Other batches

名为Users的表在事务中与其他批一起更新,当过程正在进行时,Users表被锁定,即使使用
nolock
hint,我也无法从中选择

BEGIN TRY 
BEGIN TRANSACTION
---------------------------Apply Users Changes-----------------------------


      ALTER TABLE Security.Users NOCHECK CONSTRAINT ALL;


   ...Other batches

    BEGIN
    DECLARE @usersCount INT = (SELECT COUNT(1) FROM #xyz),
            @batchCount INT = 20,
            @batchesDone INT = 0
    WHILE @batchesDone * @batchCount < @usersCount
    BEGIN
        UPDATE Users
        SET [UserName] = ISNULL(a.UserName,a.Code),
            [Code] = ISNULL(a.[Code], '0'),
            [Password] = ISNULL([Password], dbo.HashPassword(ISNULL(a.[Code], '0'))),
            [Mobile] = a.[Mobile],
        FROM (
            SELECT * FROM #xyz
            WHERE RN > @batchesDone * @batchCount AND RN <= (@batchesDone + 1) * @batchCount
        ) a
        WHERE Users.Username = a.UserName
    
        SET @batchesDone += 1
    END
    END 


          
    ALTER TABLE Security.Users CHECK CONSTRAINT ALL;
    COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
    IF @@TRANCOUNT>0
    ROLLBACK TRANSACTION

    RAISERROR(@message,16,1)
    END CATCH

如果没有通信,它需要SQL Server在表上取出模式共享锁,这意味着另一个会话甚至无法生成查询计划。
nolock
提示不能用于忽略这些

你可以通过跑步自己看到这一点

begin transaction 
ALTER TABLE Security.Users NOCHECK CONSTRAINT ALL;
然后在另一个会话中对
security.users
执行任何查询,在另一个会话中使用Adam Machanic的
sp_whoisactive
过程()检查发生了什么。您会看到查询会话正在等待
LCK\u M\u schu S
,您可以在其中搜索

正如我在前面的评论中所解释的,禁用支票约束实际上不太可能对您有任何好处,我建议您不要这样做。如果您确实想要,那么只需在显式事务之外调用它,这样它就可以立即提交(并允许其他所有人以自己喜欢的方式修改数据)


强制性警告,当您修改正在查看的数据时,
nolock
会给您逻辑上不一致的数据。

首先为什么要使用
nolock
?你知道使用暗示的后果,对吗?对表使用它执行
更新
是一种灾难。那么我该怎么办?当过程正在运行时,我的整个应用程序停止工作。摆脱
,而
将是一个开始,或者至少增加批处理大小;设计良好的数据库可以在几秒钟或更短的时间内处理数百万行。只需20行就可以成批处理所有这些行,这对性能来说是非常糟糕的。当然,对update语句进行批处理的整个意义在于,您可以在每个批之间进行提交。我建议禁用您的检查约束是一个坏主意,不会给您带来任何改进(除非它们是超级复杂的正则表达式)。。但是,如果您必须并且理解其后果,并且您接受您的代码不能始终正常工作,那么至少使用当前语法,而不是不推荐使用的语法。发展如果它突然出现异常怎么办?我应该使用ALTER TABLE Security吗?用户检查catch块中的所有约束?您是否确实确定它对您有帮助?如果您要这样做(并且允许其他会话忽略您的检查约束),那么就完全在try-catch块之外进行。T-SQL没有
最终
(奇怪的是),所以你只能把它放在外面
ALTER TABLE Security.Users NOCHECK CONSTRAINT ALL;
begin transaction 
ALTER TABLE Security.Users NOCHECK CONSTRAINT ALL;