关于DeadLock的问题

时间:2014-12-16 12:27:04

标签: sql-server deadlock database-administration

在这里,我有一些问题。

我会快速而简单。

我使用SQL Server 2008并且我一直面临很多关于死锁的调用。

用户说他们正在工作,然后他们会收到错误

  

事务(进程ID)在锁资源上与另一个进程发生死锁,并被选为死锁牺牲品。重新运行该交易。

所以我联系开发人员并告诉他们在查询中添加WITH (NO LOCK)

它有效率100%。

但是,这是对的吗?

有什么可以做而不是它,或者这是摆脱这些僵局的唯一方法吗?

由于

4 个答案:

答案 0 :(得分:1)

确定。因此,死锁是两个进程竞争相同的数据,但在更新它(或释放锁定)之前等待另一个进程完成。锁定数据的原因之一是防止“脏读”。即读取过时数据,因为它已经更新

因此,锁定是有原因的,即它可以保护数据的完整性。只有在您确定系统不会因此受损时,才能将其关闭(无锁定)。否则你会开始获得数据损坏,即数据不良。

我会说使用WITH(NO LOCK)是安全的,只有报告的程序,即选择没有任何后续更新,并且与系统的操作无关。对于选择然后更新不太好的程序。

根据@idstam的回答,如果您确实需要选择数据,对其做出一些决定然后进行更新,这些需要尽可能短。即,选择和更新之间的时间需要很短,因为这是锁存在的时间,因此是死锁机会的窗口。这在用户正在查看相同数据的多用户系统中更为普遍。

所以,是的,你可以拒绝锁定,但要注意它可能会给你留下不好的数据。最好的办法是了解什么是死锁,并确定它是否可以改进。如果您尝试通过降低隔离级别来最小化死锁,则需要使用行版本控制,即每次更新检查它是否正在更新它上次看到的数据,如果不是(即它在此期间已更新),则会抛出错误

Here is a good MSDN article on how to reduce deadlocks

答案 1 :(得分:0)

将数据库设置为使用行级版本控制。

保持交易短暂。

确保在所有地方以相同的顺序使用表格。

预先写入锁定有时会有所帮助。

答案 2 :(得分:0)

这取决于您对阅读一致性的关注程度以及您对表现的关注程度。

  • WITH(NO LOCK) - 没有读锁定但受到陈旧,不一致数据的影响
  • 行级版本 - 行的旧版本保留在旁边'。这也消除了对您正在进行的每个DML的额外开销成本的读锁定。

在此处阅读更多内容:http://technet.microsoft.com/en-us/library/ms188277(v=sql.105).aspx

答案 3 :(得分:0)

NOLOCK和SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED可能很有用,但并不总是正确的答案。这取决于具体情况。我认为最大的风险是脏读。 (读取因某种原因可能会回滚的数据。)

您可以在这里阅读更多内容

http://sqlblog.com/blogs/tamarick_hill/archive/2013/05/06/pros-cons-of-using-read-uncommitted-and-nolock.aspx

希望有所帮助