【问题标题】:SQLAlchemy idle in transactionSQLAlchemy 在事务中空闲
【发布时间】:2017-12-18 10:02:54
【问题描述】:

我有 Python 3.6、Flask 和 SQLAlchemy (PostgreSQL) 编写的应用程序。

我遇到了在我的数据库中挂起idle in transaction 连接的问题。这可能是因为我在选择查询后不提交也不回滚。

我使用默认的 SQLALchemy 配置:db = SQLAlchemy()

创建悬挂连接的示例端点:

class Test(Resource):

    def get(self, pk):
        return User.query.get(pk).serialize()

处理此类选择查询的方法是什么?我应该选择然后提交吗?还是选择然后回滚?或请求后完全关闭连接?但是关闭连接会导致每次请求都会打开与数据库的新连接。

最好的方法是什么?

【问题讨论】:

  • 不要关闭连接。只是请求结束时的Session 等(如果是线程本地范围的会话,请删除)。有关指针,请参阅flask.pocoo.org/docs/0.12/patterns/sqlalchemy/#declarative,但据我了解,Flask-SQLAlchemy 应该开箱即用。
  • 只有在应用拆解时才会删除会话。请求后我该怎么办?回滚?关闭会话?哪种方法更好?另外,如果我关闭会话,未提交/回滚的事务会发生什么?
  • 文档中有一篇关于该主题的冗长文章:docs.sqlalchemy.org/en/latest/orm/…。当您将scoped sessions 放入组合中时,您会希望将remove() 注册的Session 对象放在合适的位置。删除的会话将为您关闭,从而结束正在进行的事务,释放资源等。
  • 我阅读 Flask 文档会暗示 @app.teardown_appcontext 处理程序也会在请求后被触发。

标签: python flask sqlalchemy flask-sqlalchemy


【解决方案1】:

这篇文章描述了正在发生的事情以及如何处理它:http://oddbird.net/2014/06/14/sqlalchemy-postgres-autocommit/

简答:SQLAlchemy 默认隐式打开一个新事务。您可以在每次 SELECT 后提交或打开自动提交(阅读文章了解更多信息)。

这是关于此事的 SO 帖子。
sqlalchemy, postgresql and relationship stuck in "idle in transaction"

【讨论】:

  • 所以可以禁用自动提交模式,但它很hacky和有风险吗?此外,SQLAlchemy 文档说自动提交模式是遗留的。这是否意味着使用自动提交模式可能很危险?根据 SOIt unfortunate that Session.begin() does not always mean BEGIN TRANSACTION;
  • 自动提交很少是一个好的解决方案。确定会话/连接应该在哪里提交/回滚/关闭会更好。通常会话的生命周期与请求等相关。
  • 所以我想在我的BaseEndpoint 课程中,在 dispatch_request 之后进行。我认为更好的解决方案是在这里回滚而不是提交?所以我只保留在请求期间明确提交的事务,所有其他事务都将被回滚。你怎么看?
  • 谢谢大哥
猜你喜欢
  • 2014-03-23
  • 1970-01-01
  • 2013-08-28
  • 1970-01-01
  • 2015-05-16
  • 2013-10-15
  • 1970-01-01
  • 2015-06-22
  • 2020-12-27
相关资源
最近更新 更多