2

ここで私の状況。

クライアントからデータを受信し、このデータからイベントを作成するRESTful Webサービスを構築しています。次に、この新しいイベントをセロリにプッシュして非同期的に処理したいと考えています。

ピラミッドを使用して RESTful Web サービスを構築し、pyramid_celery を使用してピラミッドとセロリを連携させます。

ここに私のビューのソースコード:

# views.py
# This code recive data from client, then create a new record Event from this

posted_data = schema.deserialize(request.POST.mixed())

e = Event()
e.__dict__.update(posted_data)
DBSession.add(e)
transaction.commit()

print "Commited #%d" % e.id # code mark 01
fire_event.delay(e.id) # fire_event is a celery task
logging.getLogger(__name__).info('Add event #%d to tasks' % e.id)

ここに私のタスクのソースコードがあります:

# tasks.py
@celery.task()
def fire_event(event_id):
    e = DBSession.query(Event).get(event_id)

    if e is None:
        return

    print "Firing event %d#%s" % (event_id, e)
    logger.info("Firing event %d#%s", event_id, e)

ピラミッドの錬金術足場のデフォルト コードを使用すると、コード マーク 01行で例外が発生します。そのような例外:

DetachedInstanceError: Instance <Event at ...> is not bound to a Session; ...

ZopeAlchemy ドキュメントから、この例外を回避するために、DBSession を次のように構成します。

# models.py
DBSession = scoped_session(sessionmaker(
                extension=ZopeTransactionExtension(keep_session=True)
            ))

今私の問題は、RESTful リクエストが終了した後、MySQL サーバーとのピラミッド キープ トランザクションです。RESTful リクエストが終了したら、MySQL Server に移動して次のコマンドを実行します。

SHOW engine innodb status;

その結果から、次のことがわかります。

--TRANSACTION 180692, ACTIVE 84 sec
MySQL thread id 94, OS thread handle 0x14dc, query id 1219 [domain] [ip] [project name] cleaning up
Trx read view will not see trx with id >= 180693, sees < 180693

これは、Pyramid がまだ接続を維持していることを意味します。問題ありませんが、Pyramid はトランザクションも開始します。これは問題です。このトランザクションにより、別のツールを使用して MySQL サーバーにアクセスしようとすると、ロック状態になる可能性があります。

私の質問は:

RESTful リクエストが終了したらすぐに Pyramid にトランザクションをクローズさせるにはどうすればよいですか? できない場合、私の状況に対する別の解決策はありますか?

どうもありがとう。

4

1 に答える 1