我遇到了偶尔会陷入僵局的网络应用程序
涉及3个查询。 2正在尝试更新表
UPDATE AttendanceRoll
SET ErrorFlag = 0
WHERE ContractID = @ContractID
AND DATEPART(month,AttendanceDate) = DATEPART(month,@Month_Beginning)
AND DATEPART(year,AttendanceDate) = DATEPART(year,@Month_Beginning)
一个人正试图插入表格
INSERT INTO AttendanceRoll
(AttendanceDate, ContractID, PersonID,
StartTime,
EndTime,
Hours, AbsenceReason,
UpdateCount, SplitShiftID, ModifiedBy, ModifiedDate)
SELECT
@P33, @P34, @P35,
CONVERT(datetime,REPLACE( @P36, '.', ':')),
CONVERT(datetime,REPLACE( @P37, '.', ':')),
@P38, @P39,
@P40, 1, @P41, GETDATE()
死锁图显示了一种页面锁定和交换事件的循环排列,并且2个更新查询具有相同的服务器进程ID。
如果有人对如何解决这个问题有任何想法,那将非常感激。
如果有人需要,我可以发布死锁图。
由于 Carl R
答案 0 :(得分:1)
更新查询是否需要花费大量时间才能执行(例如,超过秒)?如果是这样,请尝试优化查询(即通过将索引放在contractid列等)
在修复死锁时我总是喜欢做的第一件事就是调整所涉及的查询。如果您可以获得良好的性能提升,那么您将获得更快查询的好处,同时大大降低发生死锁的可能性。
答案 1 :(得分:1)
- 在jorgeburgos的建议之后,然后......
如果它陷入僵局,假设只有2名参赛者,一名应该是受害者,一名将完成。
您可以在数据层中构建死锁检测,并让它重试失败导致死锁的操作。
使用不同的表提示锁定机制来最小化所争议的资源范围。我不知道哪个适用于您正在使用的sql版本,但这里是来自MSDN。 http://msdn.microsoft.com/en-us/library/ms187373.aspx
答案 2 :(得分:1)
没有查看死锁图表和所涉及的工作负载,并且基于您所说的有关交换的内容,您可能会遇到涉及并行性的死锁。 http://msdn.microsoft.com/en-us/library/aa937571(SQL.80).aspx。您的死锁图形是否与上一篇文章中的一样?
您可以为查询禁用parralesim吗?有一个提示OPTION(MAXDOP 1)将在特定查询中禁用它。打开它,看看它是否有帮助。 http://msdn.microsoft.com/en-us/library/ms181714.aspx
优化索引也可以通过首先消除对parallesim的需求来缓解僵局。
答案 3 :(得分:1)
我猜你的更新正在进行表扫描,并最终将行锁升级为页锁到表锁,这会阻止插件完成
我认为有一个设置告诉它不要升级到行锁定之外,你可以尝试第一次
如果不这样做,您可能必须将月份数据分开并编制索引以使更新更有效
答案 4 :(得分:0)
我通常将我对SQL服务器的所有调用都包含在类似的内容中(确切地说这不会编译,但你会得到这个想法):
for (;;) {
try {
using (var t = BeginTransaction()) {
DoTheCall();
t.Commit();
return;
}
}
catch (SqlException ex) {
if (ex.Number != 1205 && ex.Number != 601 && ex.Number != 605)
throw;
}
}