可能有人给我时,我应该使用一些指导WITH (NOLOCK),而不是SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
每个的优点/缺点是什么?是否有任何意外的后果,你使用一个而不是另一个?
我们在Stack Overflow SQL Server 2005数据库中看到了一些有害但罕见的死锁条件.
我附上了探查器,使用这篇关于解决死锁问题的优秀文章设置了一个跟踪配置文件,并捕获了一堆示例.奇怪的是,死锁写入始终是相同的:
UPDATE [dbo].[Posts]
SET [AnswerCount] = @p1, [LastActivityDate] = @p2, [LastActivityUserId] = @p3
WHERE [Id] = @p0
Run Code Online (Sandbox Code Playgroud)
另一个死锁声明各不相同,但它通常是对posts表的一些简单,简单的读取.这个人总是在僵局中被杀死.这是一个例子
SELECT
[t0].[Id], [t0].[PostTypeId], [t0].[Score], [t0].[Views], [t0].[AnswerCount],
[t0].[AcceptedAnswerId], [t0].[IsLocked], [t0].[IsLockedEdit], [t0].[ParentId],
[t0].[CurrentRevisionId], [t0].[FirstRevisionId], [t0].[LockedReason],
[t0].[LastActivityDate], [t0].[LastActivityUserId]
FROM [dbo].[Posts] AS [t0]
WHERE [t0].[ParentId] = @p0
Run Code Online (Sandbox Code Playgroud)
要非常清楚,我们没有看到写/写死锁,而是读/写.
我们目前混合使用LINQ和参数化SQL查询.我们已添加with (nolock)到所有SQL查询中.这可能对一些人有所帮助.我们昨天修复了一个(非常)写得不好的徽章查询,每次运行时间超过20秒,每分钟运行一次.我希望这是一些锁定问题的根源!
不幸的是,我在大约2小时前遇到了另一个死锁错误.同样的症状,同样的罪魁祸首写.
真正奇怪的是,您在上面看到的锁定写入SQL语句是非常特定的代码路径的一部分.它仅在向问题添加新答案时执行 - 它使用新答案计数和最后日期/用户更新父问题.显然,这与我们正在进行的大量读取相比并不常见!据我所知,我们在应用程序的任何地方都没有进行大量的写操作.
我意识到NOLOCK是一个巨大的锤子,但我们在这里运行的大多数查询都不需要那么准确.如果您的用户个人资料已过期几秒,您会关心吗?
正如Scott Hanselman在这里讨论的那样,将NOLOCK与Linq一起使用有点困难.
我们正在调整使用的想法
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Run Code Online (Sandbox Code Playgroud)
在基本数据库上下文中,以便我们所有的LINQ查询都有此设置.没有它,我们必须在3-4行事务代码块中包装我们所做的每个LINQ调用(好吧,简单的读取,这是绝大多数),这很难看.
我想我有点沮丧的是,SQL 2005中的琐碎读取可能会使写入死锁.我可以看到写/写死锁是一个很大的问题,但 …
我很少(每月/每季度)使用Microsoft SQL Server 2005数据库视图生成数百个Crystal Reports报告.这些视图是否在我不读取它们的过程中浪费CPU周期和RAM?我是否应该使用存储过程,临时表或短命的普通表,因为我很少从我的视图中读取?
我不是DBA所以我不知道数据库服务器内幕后发生了什么.
是否可能有太多的数据库视图?什么是最佳做法?
我们正在评估EF4,我的DBA说我们必须在所有SELECT语句中使用NOLOCK提示.所以我正在研究如何在使用EF4时实现这一点.
我已经阅读了关于如何在EF4中实现这一点的不同想法,但所有这些似乎都是一种解决方案而不是微软或EF4批准的.在使用LINQ-to-SQL/LINQ-to-Entities和EF4时,希望他们的SELECT语句包含NOLOCK提示的人的"官方Microsoft"响应是什么?
顺便说一下,我发现的绝对最好的信息就在这里,我鼓励每个对这个主题感兴趣的人阅读这个主题.
谢谢.
我的老板一直强迫我编写 SELECT 查询以with (nolock)防止死锁。但据我所知,Select 语句默认没有锁,因此选择 withwith (nolock)和选择 without 没有任何区别。如果我错了,请纠正我。
两个查询:
SELECT * from EMP with (nolock)
SELECT * from EMP
Run Code Online (Sandbox Code Playgroud)
两者不是一样的吗。如果不加nolock会不会容易出现死锁?请告诉我应该使用什么。
免责声明:这不是关于NOLOCK问题的一般性问题(因此不是NOLOCK(Sql Server提示)错误做法的重复吗?); 这是一个特定的问题,关于NOLOCK和DISTINCT如何交互以试图更好地理解SQL Server的内部工作.
虽然看起来很奇怪,但在我看来,NOLOCK可能会导致DISTINCT在某种情况下失败.这是一个例子:
INSERT INTO TableA (ID)
SELECT DISTINCT ID
FROM TableB WITH (NOLOCK)
Run Code Online (Sandbox Code Playgroud)
以上示例偶尔会产生PK违规.以下是其他相关事实:
我的工作理论是:1)TableB上的更新与NOLOCK的使用相结合导致重复数据,2)优化器依赖于TableA在同一列上具有PK的事实,我们是DISTINCTing,因此不会t主动对正在返回的行执行DISTINCT操作,它只是假设行已经是不同的.
谁能证实这一点?如果是这样,这是设计,还是SQL Server中的错误?
我原本以为即使有脏读也有重复行的可能性,DISTINCT将是清理重复项的保证,但我看到的证据似乎表明不是这样.
在SQL Server 2008R2上看到此错误.
我在msdn中找到了一些文档,它说"没有发出共享锁来阻止其他事务修改当前事务读取的数据".
因此,在非专业术语(即我的)中,这将导致脏读的问题.哪个太危险了,如果是的话那么为什么要用呢?
有没有人知道它将被使用的实际场景.
我曾经在一个非常大的组织工作,他们必须NOLOCK在大多数查询中使用- 因为数据通常在白天通过ETL进程更新,并且锁定应用程序40%的工作日当然不是一种选择.
出于习惯,在我的下一个地方,我继续自动使用NOLOCK到处.但是,自从阅读警告和风险以来,我一直在逐步撤消这一点,没有指定任何表提示,让SQL Server做到这一点.
但是,我仍然不舒服我正在做正确的事情.在我们使用的地方NOLOCK,我从来没有看到数据加倍,或数据损坏..我在那里已经很多年了.自从删除以来,NOLOCK我遇到了明显阻碍行阻塞的问题,这些障碍减缓/暂停了查询,从而产生了我的数据库缓慢或松散的错觉.实际上,只是有人在某处运行冗长的保存(他们这样做的能力是应用程序的要求).
我很想听听任何NOLOCK在实践中经历过数据损坏或数据重复的人,而不是那些在互联网上阅读过他们的人.如果有人能提供复制步骤来看到这种情况,我将特别感激.我试图衡量它的风险程度,风险是否超过能够运行与更新平行的报告的明显好处?
在我的SQL tempOrder表中有数百万条记录,并有10个触发器tempOrder用另一个表的更新来更新表.
所以我想with(NOLOCK)在桌子上申请申请.
我知道
SELECT * FROM temporder with(NOLOCK)
我可以做这个陈述.但有没有办法with(NOLOCK)从SQL Server 2008直接应用于表.
在以下查询中我将放置在哪里WITH(NOLOCK)?
SELECT *
FROM (SELECT *
FROM (SELECT *
FROM (SELECT *
FROM (SELECT *
FROM dbo.VBsplit(@mnemonicList, ',')) a) b
JOIN dct
ON dct.concept = b.concept
WHERE b.geo = dct.geo) c
JOIN dct_rel z
ON c.db_int = z.db_int) d
JOIN rel_d y
ON y.rel_id = d.rel_id
WHERE y.update_status = 0
GROUP BY y.rel_id,
d.concept,
d.geo_rfa
Run Code Online (Sandbox Code Playgroud) 根据 DBA 的建议,在我们的应用程序中,我们没有为使用的每个选择查询添加锁定提示。
因此,它需要修改每个选择查询以设置表提示,并且需要手动执行。
由于我们想在数据库中的所有表中使用提示,是否可以在数据库级别设置无锁提示(或TRANSACTION ISOLATION LEVEL READ UNCOMMITTED),以便不需要修改每个查询并将表提示应用于所有查询?
SELECT DISTINCT dbo.ufn_GetuserEmailId(hrb.UserID)
,''
,''
,0
,hrb.RID
,0
,'Photon Registration'
,(
CASE
WHEN hrb.SourceID = 51
THEN 10655 /*10517*/
WHEN hrb.SourceGroupID = 1
THEN 10518
WHEN hrb.SourceID = 4
THEN 10656 /*10519*/
WHEN hrb.SourceID = 1
THEN 10657 /*10520*/
END
)
,GETUTCDATE()
,hrb.UserID
,0
FROM HC_RESUME_BANK hrb WITH (NOLOCK)
INNER JOIN HC_USER_MAIN hum WITH (NOLOCK) ON hrb.UserID = hum.RID
WHERE (
hrb.SourceID IN (
51
,1
)
OR (hrb.SourceGroupID = 1)
OR (
hrb.SourceID = 4
AND isnull(hrb.SourceEmailId, '') <> …Run Code Online (Sandbox Code Playgroud)