You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pyodbc查询SQL Server时cursor.fetchall()死锁,如何正确恢复?

死锁后正确的恢复方式:重新执行完整查询流程

当遇到fetchall()抛出死锁异常的情况,必须重新执行cursor.execute(),再调用fetchall(),不能只单独重试fetchall()。

原因很明确:SQL Server判定你的查询进程为死锁受害者后,会直接终止该查询的数据库端执行上下文。哪怕之前execute()调用成功,也只是完成了查询请求的发送,数据库并没有保留可用的结果集(或已准备的结果集被销毁),此时cursor已经没有有效数据可读取,单独重试fetchall()只会持续报错。

正确的重试逻辑需要包含完整的查询流程,示例代码如下:

import pyodbc

# 假设self.cursor已完成初始化
max_retries = 3
retry_count = 0
results = None

while retry_count < max_retries:
    try:
        self.cursor.execute(sql, *values)
        self.rowcount = self.cursor.rowcount
        results = self.cursor.fetchall()
        break  # 成功获取结果,退出重试循环
    except pyodbc.Error as e:
        # 识别死锁错误(错误码1205)
        if '1205' in str(e.args[0]):
            retry_count += 1
            print(f"遭遇死锁,正在重试第{retry_count}次")
        else:
            # 非死锁异常直接抛出
            raise

if not results:
    raise RuntimeError("经过3次重试后仍无法完成查询,死锁问题持续存在")

需要注意:重试只是临时恢复手段,长期来看应该排查死锁根源——比如通过SQL Server死锁图分析资源竞争情况,优化查询语句、添加合适索引,或调整事务隔离级别(如启用READ COMMITTED SNAPSHOT)来降低死锁发生率。

内容的提问来源于stack exchange,提问作者Sergey Nudnov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:22:05