【发布时间】:2013-10-07 02:22:27
【问题描述】:
最近,当我们去更新我们的一个表中的记录时,我们遇到了错误Transaction ABORTed due to Deadlock。有东西在这张桌子上加了一把锁,它没有被释放,但我花了几天的时间试图追踪它,但它仍然让我难以捉摸。
虽然错误是随机的,但我确实知道我需要重复哪些重复步骤才能最终触发它。但是,我查询了 dbc.DBQLogTbl 并查看了在错误发生前后 2 分钟执行的所有 SQL,并且在没有访问锁的情况下似乎没有从任何表中进行选择。此外,发生错误后,我将按 F5 将 Web 表单重新发布回服务器以重复完全相同的更新集,它会起作用。
我的预感是我们的 ASP.NET 应用程序之外的某个进程正在锁定表,因为我已经检查了我们的应用程序正在执行的所有 SQL。我认为必须有一种方法可以找出执行了哪些特定的 SQL 并在表上加了锁。
2012 年 8 月 9 日附加信息:根据我在查询dbc.DBQLogTbl 和通过firststeptime 订购时看到的情况,在同一事务中按此顺序发生以下所有情况:
- 更新员工表
- locking row for access select * from employeesecurity where empid = X(执行此操作以获取当前员工记录以查看是否有任何更改)
- 如果有变化,更新上述员工安全记录
- 更新employeeconfig表(这里总是出现死锁错误)
我之前没有提到这一点,但是死锁错误发生在我根本没有从中选择的表上。当页面加载时,我确实从一个employeeconfig 视图中读取,但在视图中指定了locking row for access。
回答 Rob 的 4 个问题:
- 这只是一笔交易。
- 正如我在最新更新中所述,被锁定的表甚至不是从中选择的表。
- 所有查询都使用
locking row for access - 我们正在从视图
employeeconfig中进行选择。此视图使用locking row for access从employeeconfig表中进行选择。我们在查询视图本身时不使用locking row for access。
就处理死锁而言,我不希望代码只是尝试重新提交它,因为这似乎是一个需要修复的问题。正如你所说,Rob,我对dbc.DBQLogTbl 的访问可能受到限制,所以我可能无法看到正在发生的一切。我一直在联系 DBA,今天会再次跟进。
【问题讨论】:
-
我认为如果您遇到死锁错误,您的应用程序至少会尝试一次重试已中止的事务。您的环境是否使用 Viewpoint?如果是这样,您是否可以将其与 Rewind 功能和 Query Monitor portlet 一起使用?
-
是的,我们使用视点,但我没能弄清楚。我尝试使用从查询 dbc.DBQLogTbl 中获得的会话 ID,但 ViewPoint 似乎从未找到它。此外,查询监视器中的 SQL 选项卡始终显示为灰色。有没有其他方法可以找出哪些 SQL 锁定了表,或者 ViewPoint 几乎是唯一的选择?
-
Viewpoint 只会帮助识别在您的事务中止时处于活动状态的其他会话。根据在 Viewpoint 上为您的角色设置的 portlet 权限,SQL 可能不可见。 (参见 DBA 团队。)
-
更新语句的“EmployeeConfig”表的锁定级别是多少?我假设您正在执行单行更新并在主索引上进行限定。
-
是的,主索引上的单行更新。我没有为更新指定任何锁定。基本上,我只是使用
update employeeconfig set field = x where id = y。