Python + SQLAlchemy问题:由于子事务回滚,事务处于不活动状态
我在使用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() 这个方法会清空会话,并关闭任何未完成的事务(如果有的话)。你需要确保每次使用会话时,在控制器的工作完成后都要清空它。在控制器处理请求的开始阶段这样做,可以确保会话总是被清空,即使之前的请求出现了异常,还有一个回滚在等待。