Python + SQLAlchemy问题:由于子事务回滚,事务处于不活动状态

2 投票
2 回答
2791 浏览
提问于 2025-04-16 00:33

我在使用Python和SQLAlchemy的时候遇到了一个问题。

当出现错误时(在我的情况下是因为竞争条件导致的完整性错误),数据库会抛出一个错误,这样之后的所有请求都会出现同样的错误:

InvalidRequestError: The transaction is inactive due to a rollback in a subtransaction.  Issue rollback() to cancel the transaction.

虽然我可以防止这个最初的错误(竞争条件)发生,但我希望有一个更稳健的解决方案,我想防止一个错误导致整个应用程序崩溃。

有什么好的方法可以做到这一点吗?有没有办法告诉Python回滚失败的事务?

2 个回答

0

你在你的控制器里用到 yoursapp.lib.base.BaseController 吗?

你可以看看这个链接: 处理 SQLAlchemy 中的 MySQL 重启

你也可以在 BaseController 的 try-finally 代码块中捕获 SA 异常,并执行 session 的 rollback() 操作。

在 BaseController 中,SA Session 的生命周期可以参考这个链接: http://www.sqlalchemy.org/docs/05/session.html#lifespan-of-a-contextual-session

3

最简单的方法就是在你开始处理控制器的工作时,确保使用一个新的 SQLAlchemy 会话。在 /project/lib/base.py 文件中,为 BaseController 添加一个方法:

def __before__(self):
    model.Session.close()

Session.close() 这个方法会清空会话,并关闭任何未完成的事务(如果有的话)。你需要确保每次使用会话时,在控制器的工作完成后都要清空它。在控制器处理请求的开始阶段这样做,可以确保会话总是被清空,即使之前的请求出现了异常,还有一个回滚在等待。

撰写回答