2012-11-02 87 views
0

我试图在查看页面的人(它增加查看的计数)时更新表中的一行,但是现在然后我得到一个死锁错误,我猜这是由于到两个或更多的人试图更新同一行?SQL - 导致死锁错误的更新

的错误是:

Transaction (Process ID 60) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

我的SQL是:

UPDATE [ProductDescription] 
SET [ViewCount] = ([ViewCount] + 1) 
WHERE ProductCode = @prodCode 
    AND ApplicationID = @AppID 

我认为我可能需要WITH(NOLOCK)?

+0

您应该从[使用SQL Server Profiler分析死锁]开始(http://msdn.microsoft.com/en-us/library/ms188246(v = sql.100).aspx) –

+0

不要使用WITH (NOLOCK)',你应该考虑检查你的事务隔离级别和索引。正确的索引可以减少争用。 –

+0

谢谢,我添加了一个索引,希望能大大减少错误! – dhardy

回答

-1

事务隔离级别设置为SERIALIZABLE或快照更新数据properly.For详情检查HERE

+0

Seriazizable可能会导致进一步的死锁,因为锁将保持到交易结束 –

+0

请参阅每次更新都将在交易中进行更新,其他更新将等待完成第一个更新。如何进一步锁定您是否可以解释? – AnandPhadke

+0

如果事务在访问其他表之后访问另一个表,并且其他事务首先访问了不同的表 –

0

你不需要NOLOCK。这只会删除读锁,并会导致不可预知的结果。更好的做法是在update语句上使用TABLOCK,这意味着其他进程在完成之前无法访问表。

+0

我同意'WITH(NOLOCK)'不好,但肯定'ROWLOCK'不会使其它进程无法访问**表**直到完成。* TABLOCKX'会实现这个目标,不是吗? –

+0

是的,错字,编辑!谢谢 –

+0

“WITH(NOLOCK)很糟糕”。真?看看他们在任何地方使用的一些内置系统SP。还要考虑到这相当于READ UNCOMMITTED。它只是一个不同的粒度级别 - 仅此而已。 –

-1

问题更可能是由用户同时运行选择引起的。默认隔离级别是“读取已提交”,这会导致锁定。

除非是至关重要的,你正在阅读的数据是最新的,可以考虑使用:

with(nolock) 
在选择

或替代隔离级别。

+0

除非您正在执行诸如填充下拉列表之类的操作,否则NOLOCK总是失去一个好主意。请记住,这不仅仅是因为你可以阅读脏数据,你也可以得到重复的结果等,因为页面混洗 –

+0

DB编程中绝对数量很少,WITH(NOLOCK)就是其中之一。您需要仔细考虑您是否关心陈旧的数据。大多数时候你没有。看到这里:http://stackoverflow.com/questions/1452996/is-the-nolock-sql-server-hint-bad-practice –

+0

我当然不建议把他们像纸屑扔。如果你有很多不断更新和阅读的表,你需要查看隔离级别。 –