0

SQLALchemy 0.7.8、Flask-SQLAlchemy 0.16、MySQL 5.5を使用すると、次の問題が発生します。

サーバーAで実行されているcronスクリプトがあり、特定のステータスに一致するすべての行のIDをテーブルTに照会し、それらのIDをブローカーに送信します。ブローカーはそれを他の多くのマシンのワーカーに配布します。

ワーカーはIDを取得し、そのテーブルTと他のいくつかのテーブルにデータを照会し、テーブルを更新してそのIDを処理済みとしてマークし、トランザクションをコミットして、RESTAPIを介してサーバーXに送信します。

そのサーバーXはジョブを完了すると、結果を別のサーバーYの別のREST APIのコールバックに送信します。サーバーYは処理を実行し、結果をテーブルTに保存します。それをコミットした後、IDを別のサーバーに送信します。ワーカー。最初のステップで取得したのと同じである可能性があり、そのワーカーは他のデータを取得して別のサービスに送り返すことになっていますが、このステップでは更新を行いません。

問題は、この最後のステップで、ワーカーがコールバックを介してサーバーYによって更新されたデータを取得せず、その更新前からデータを取得することです。

ワーカーが最初にサーバーXにデータを送信するために使用したセッションにまだいると思いましたが、サーバーYがコールバックされたときに、ワーカーが次にデータをクエリするときにコミットまたはロールバックが発生しなかったため、更新されません。

この場合の適切な解決策は何ですか?これまでのところ、ワーカーがデータをクエリする前に、タスクの最初にsession.commit()を呼び出してみましたが、機能しているように見えますが、それについてはよくわかりません。

4

2 に答える 2

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

于 2013-01-26T15:08:44.470 に答える
0

この問題に関する議論はhttps://groups.google.com/forum/?fromgroups=#!topic/sqlalchemy/yXSroyVNKYMで行われました。

于 2013-01-26T02:10:34.230 に答える