在这里,我有一些问题。
我会快速而简单。
我使用SQL Server 2008并且我一直面临很多关于死锁的调用。
用户说他们正在工作,然后他们会收到错误
事务(进程ID)在锁资源上与另一个进程发生死锁,并被选为死锁牺牲品。重新运行该交易。
所以我联系开发人员并告诉他们在查询中添加WITH (NO LOCK)
。
它有效率100%。
但是,这是对的吗?
有什么可以做而不是它,或者这是摆脱这些僵局的唯一方法吗?
由于
答案 0 :(得分:1)
确定。因此,死锁是两个进程竞争相同的数据,但在更新它(或释放锁定)之前等待另一个进程完成。锁定数据的原因之一是防止“脏读”。即读取过时数据,因为它已经更新
因此,锁定是有原因的,即它可以保护数据的完整性。只有在您确定系统不会因此受损时,才能将其关闭(无锁定)。否则你会开始获得数据损坏,即数据不良。
我会说使用WITH(NO LOCK)是安全的,只有报告的程序,即选择没有任何后续更新,并且与系统的操作无关。对于选择然后更新不太好的程序。
根据@idstam的回答,如果您确实需要选择数据,对其做出一些决定然后进行更新,这些需要尽可能短。即,选择和更新之间的时间需要很短,因为这是锁存在的时间,因此是死锁机会的窗口。这在用户正在查看相同数据的多用户系统中更为普遍。
所以,是的,你可以拒绝锁定,但要注意它可能会给你留下不好的数据。最好的办法是了解什么是死锁,并确定它是否可以改进。如果您尝试通过降低隔离级别来最小化死锁,则需要使用行版本控制,即每次更新检查它是否正在更新它上次看到的数据,如果不是(即它在此期间已更新),则会抛出错误
答案 1 :(得分:0)
将数据库设置为使用行级版本控制。
保持交易短暂。
确保在所有地方以相同的顺序使用表格。
预先写入锁定有时会有所帮助。
答案 2 :(得分:0)
这取决于您对阅读一致性的关注程度以及您对表现的关注程度。
在此处阅读更多内容:http://technet.microsoft.com/en-us/library/ms188277(v=sql.105).aspx
答案 3 :(得分:0)
NOLOCK和SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED可能很有用,但并不总是正确的答案。这取决于具体情况。我认为最大的风险是脏读。 (读取因某种原因可能会回滚的数据。)
您可以在这里阅读更多内容
希望有所帮助