SQLAlchemy工作与服务器之间的事务隔离

时间:2013-01-25 16:12:40

标签: mysql concurrency sqlalchemy

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

我在服务器A上运行了一个cron脚本,它在表T中查询与特定状态匹配的所有行的id,将这些id发送给代理,代理将其分发给许多其他机器上的worker。

worker获取id,查询表T和其他一些数据表,更新表以将该id标记为正在处理,提交事务,并通过REST API将它们发送到服务器X.

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

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

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

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

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

问题是长时间运行的事务,虽然可以通过管理会话而不是使用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