我有一个执行TableB
to连接的存储过程TableA
:
SELECT <--- Nested <--- TableA
Loop <--
|
---TableB
同时,在事务中,将行插入到TableA
中,然后再插入到 中TableB
。
这种情况偶尔会导致死锁,因为存储过程 select 从TableB抓取行,而 insert 将行添加到TableA,然后每个人都希望对方放手另一个表:
INSERT SELECT
========= ========
Lock A Lock B
Insert A Select B
Want B Want A
....deadlock...
逻辑要求INSERT
首先将行添加到A,然后添加到B,而我个人并不关心 SQL Server 执行连接的顺序 - 只要它连接即可。
修复死锁的常见建议是确保每个人都以相同的顺序访问资源。但在这种情况下,SQL Server 的优化器告诉我相反的顺序是“更好”。我可以强制执行另一个连接顺序,并且执行更差的查询。
但我应该吗?
我是否应该现在和永远使用我希望它使用的连接顺序来覆盖优化器?
或者我应该只捕获错误本机错误 1205,然后重新提交选择语句?
问题不是当我覆盖优化器并让它做一些非最优的事情时查询可能会执行多糟糕。问题是:自动重试比运行更糟糕的查询更好吗?