我们的客户端代码检测到死锁,等待一段时间,然后重试请求最多 5 次。重试逻辑根据错误号 1205 检测死锁。
我的目标是测试各种存储过程中的死锁重试逻辑和死锁处理。我可以使用两个不同的连接创建死锁。但是,我想在单个存储过程本身内部模拟死锁。
死锁会引发以下错误消息:
消息 1205,第 13 级,状态 51,第 1 行
事务(进程 ID 66)在锁定资源上与另一个进程死锁,并已被选为死锁牺牲品。重新运行事务。
我看到此错误消息在 sys.messages
中:
select * from sys.messages where message_id = 1205 and language_id = 1033
message_id language_id severity is_event_logged text
1205 1033 13 0 Transaction (Process ID %d) was deadlocked on %.*ls resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
我无法使用 RAISERROR
引发此错误:
raiserror(1205, 13, 51)
消息 2732,第 16 层,状态 1,第 1 行
错误号 1205 无效。该数字必须从 13000 到 2147483647,并且不能是 50000。
我们的死锁重试逻辑检查错误号是否为 1205。死锁需要与普通死锁具有相同的消息 ID、级别和状态。
有没有办法模拟死锁(使用 RAISERROR 或任何其他方式)并 仅通过一个进程 获得相同的消息编号?
我们的数据库使用 SQL 2005 兼容性,尽管我们的服务器从 2005 到 2008 R2 有所不同。
原文由 Paul Williams 发布,翻译遵循 CC BY-SA 4.0 许可协议
正如许多人指出的那样,答案是否定的,单个进程本身无法可靠地死锁。我想出了以下解决方案来模拟开发或测试系统上的死锁。
在 SQL Server Management Studio 窗口中运行以下脚本。 (仅在 2008 R2 上测试。)您可以根据需要让它一直运行。
在要模拟死锁的地方,插入对
sp_simulatedeadlock
的调用。运行您的进程,应该会发生死锁。完成测试后,停止 SSMS 查询并运行底部的清理代码。