偶尔我会在生产环境中遇到以下错误,这会在再次运行相同的存储过程时消失。
事务(进程ID 86)在锁资源上与另一个进程发生死锁,并被选为死锁牺牲品。重新运行交易
有人告诉我,如果我在我的存储过程中使用NOLOCK提示,它将确保它永远不会死锁。它是否正确?有没有更好的方法来处理这个错误?
答案 0 :(得分:5)
预计会像SQL Server / Sybase一样锁定RDBMS上的偶然死锁。
您可以在客户端上进行编码,以按照推荐的MSDN "Handling Deadlocks"重试。 基本上,检查SQLException,也许半秒后再试一次。
否则,您应该检查您的代码,以便对表的所有访问权限都是相同的。或者您可以使用SET DEADLOCK_PRIORITY来控制谁成为受害者。
在MSDN for SQL Server上,"Minimizing Deadlocks"启动
虽然死锁无法完全避免
这也提到了“使用较低的隔离级别”,我不喜欢(与SO上的许多SQL类型相同),这是你的问题。不要这样做是答案......: - )
注意:MVCC类型RDBMS(Oracle,Postgres)没有此问题。请参阅http://en.wikipedia.org/wiki/ACID#Locking_vs_multiversioning,但MVCC has other issues.
答案 1 :(得分:4)
虽然添加NOLOCK可以防止读者和作者互相阻塞(更不用说它所带来的所有负面影响),但它并不是解决死锁的神奇方法。许多死锁与读取数据没有任何关系,因此将NOLOCK应用于您的读取查询可能不会导致任何改变。您是否运行了跟踪并检查了死锁图以确切了解死锁是什么?这至少应该让您知道要查看的代码部分。例如,存储过程是否会死锁,因为多个用户同时调用它,或者是否使用不同的代码进行死锁?
答案 2 :(得分:0)
Here is a good link on learning to troubleshoot deadlocks。由于上述原因,我总是尽量避免使用nolock。您也可以更好地了解Lock Compatibility。