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

Discord Bot连接MySQL遇2006错误及PendingRollbackError的解决咨询

MySQL连接断开与事务回滚问题解决建议

核心问题分析

"MySQL server has gone away"是因为MySQL会主动断开长时间空闲的连接(默认8小时),Bot复用了失效连接;添加session.rollback()后出现的PendingRollbackError是因为事务状态异常,未正确处理会话生命周期。

具体解决方案

1. 配置SQLAlchemy连接池,自动回收失效连接

在创建引擎时添加pool_recycle和pool_pre_ping参数,提前回收连接并校验有效性:

from sqlalchemy import create_engine

# 替换为你的数据库连接信息
engine = create_engine(
    "mysql+pymysql://username:password@host/database",
    pool_recycle=3600,  # 1小时后自动回收连接,需小于MySQL的wait_timeout(默认28800秒)
    pool_pre_ping=True  # 使用连接前自动检查有效性,失效则重建
)

2. 正确处理会话与事务异常

不要随意全局添加rollback(),而是在异常捕获中针对性处理,并及时销毁失效会话:

from sqlalchemy.exc import OperationalError, PendingRollbackError
from your_module import Warning, create_session  # 替换为你的模型和会话创建函数

def fetch_user_warnings(uid):
    session = create_session()
    try:
        warning = session.query(Warning).filter_by(uid=uid).limit(1).first()
        session.commit()
        return warning
    except OperationalError:
        # 连接失效,回滚事务并关闭会话,重新创建会话重试
        session.rollback()
        session.close()
        session = create_session()
        warning = session.query(Warning).filter_by(uid=uid).limit(1).first()
        session.commit()
        return warning
    except PendingRollbackError:
        # 事务状态异常,强制回滚后重建会话
        session.rollback()
        session.close()
        session = create_session()
        warning = session.query(Warning).filter_by(uid=uid).limit(1).first()
        session.commit()
        return warning
    finally:
        # 无论成功失败,确保会话关闭
        session.close()

3. 优化会话使用习惯

  • 不在Bot全局作用域创建会话对象,每个命令处理函数内单独创建和关闭会话;
  • 检查MySQL配置中的wait_timeout和interactive_timeout,确保pool_recycle的值小于这两个参数的最小值;
  • 避免长时间保持开启的会话,数据库操作完成后立即提交/回滚并关闭会话。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:35:20