【问题标题】:SQLAlchemy transaction isolation between workers and server工作人员和服务器之间的 SQLAlchemy 事务隔离
【发布时间】:2013-01-26 23:08:44
【问题描述】:

我有以下问题,使用 SQLALchemy 0.7.8、Flask-SQLAlchemy 0.16 和 MySQL 5.5。

我有一个在服务器 A 上运行的 cron 脚本,它查询表 T 以获取与特定状态匹配的所有行的 id,将这些 id 发送到代理,该代理将其分发给许多其他机器上的工作人员。

工作人员获取 id,查询该表 T 和其他一些表的数据,更新表以将该 id 标记为正在处理,提交事务,然后通过 REST API 将这些发送到服务器 X。

一旦服务器 X 完成工作,它会将结果发送到另一个服务器 Y 的另一个 REST API 中的回调。服务器 Y 进行一些处理并将结果保存回表 T。提交之后,它发送id 给另一个工作人员,这可能是在第一步中获得它的同一个工作人员,并且该工作人员现在应该获取一些其他数据并将其发送回另一个服务,但它不会在这一步进行任何更新。

问题是,在最后一步,worker 没有通过回调获取服务器 Y 更新的数据,而是从更新之前获取的数据。

我认为工作人员仍然在它用来首先将数据发送到服务器 X 的会话中,并且没有刷新,因为在它和下一次查询数据之间没有发生提交或回滚,当服务器 Y 被调用时返回。

在这种情况下,什么是适当的解决方案?到目前为止,我尝试在任务开始时调用 session.commit(),在工作人员查询数据之前,它似乎正在工作,但我不太确定。

【问题讨论】:

    标签: mysql concurrency sqlalchemy


    【解决方案1】:

    【讨论】:

    • 你很快......我打算在讨论结束后在这里回答。
    【解决方案2】:

    问题是长时间运行的事务,虽然它可以通过管理会话而不是使用 Flask 全局 db.session 来解决,但在 Flask-SQLAlchemy 下执行此操作的正确方法是为每个任务调用创建一个新上下文.

    所以,而不是:

    def task(args):
        session = Session(engine)
        try:
           ... do stuff here
            session.commit()
        finally:
            session.close() 
    

    它只需要:

    def task(args):
        with app.app_context():
            ... do stuff here
    

    这里的相关讨论: https://groups.google.com/forum/?fromgroups=#!topic/sqlalchemy/yXSroyVNKYM

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 2015-09-02
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 2022-12-15
      相关资源
      最近更新 更多