Sql 更新内部事务时nolock提示不起作用
名为Users的表在事务中与其他批一起更新,当过程正在进行时,Users表被锁定,即使使用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
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;