トランザクションとセロリのタスクについて質問があります。したがって、同じテーブル/レコードにアクセスするトランザクションとセロリ タスクがある場合、競合状態が発生することは当然のことです。
ただし、次のコードを検討してください。
def f(self):
# function of module that inherits from models.Model
self.field_a = datetime.now()
self.save()
transaction.commit_unless_managed()
# depending on the configuration of this module
# this might return None or a datetime object.
eta = self.get_task_eta()
if eta:
celery_task_do_something.apply_async(args=(self.pk, self.__class__),
eta=eta)
else:
celery_task_do_something.delay(self.pk, self.__class__)
セロリのタスクは次のとおりです。
def celery_task_do_something(pk, cls):
o = cls.objects.get(pk=pk)
if o.field_a:
# perform something
return True
return False
ご覧のとおりtransaction.commit_unless_managed
、django トランザクションは現在管理されていないため、タスクを作成する前に呼び出してコミットする必要があります。
ただし、セロリ タスクを実行すると、フィールドfield_a
は設定されません。
私の質問:
タスクを作成する前にコミットするので、競合状態が発生する可能性はありますか?
追加情報
Postgres バージョン 9.1 を使用しています
すべてのトランザクションは READ COMMITTED 分離レベルで実行されます
エンジンを備えた別のデータベースで
dowant.lib.db.backends.postgresql_psycopg2_debugger
field_a
は既に設定されており、タスクは期待どおりに機能します。エンジンを使用dowant.lib.db.backends.postgresql_psycopg2_hstore_ready
すると、説明されている問題が発生します (エンジンに関連しているかどうかは不明です)。セロリのバージョンは2.2
さまざまなデータベースを試しました。エンジンが変更された場合を除いて、同じ動作です。だから私はこれに言及したのです。
どうもありがとう。