私には独自の解決策があると思います...これは、トランザクションがコミットされるまで、基本的にテーブル内のすべての行をロックします。(これはあまり望ましくありません)
# X is the job id to uniquely put into state 100.
with transaction.commit_on_success()
count = 0
myjob = None
for job in Job.objects.select_for_update().all():
if job.state_id == 100:
count +=1
if job.id == X:
myjob = job
if count == 0 and myjob:
myjob.state_id = 100
myjob.save()
または、どのジョブが固有の状態にあるかを追跡するロック テーブルを作成することもできます。
class StateLock(Model):
# XXX: could add an expiration column, too.
state = ForeignKey(State)
locker = ForeignKey(Job, null=True) # Use IntegerField until
# django bug 16715 is fixed!!
そして使う
# lock:
StateLock.objects.filter(state=100, locker=None).update(locker=job.id)
# unlock:
StateLock.objects.filter(state=100, locker=job.id).update(locker=None)
注: django バグ 16715 が修正されるまで、null 許容の外部キーは壊れています。それ以外の場合、生成されたクエリは正しくありません。PositiveIntegerField で置き換えます。