0
如何根據當前值更新模型字段並避免競爭條件?更新任務可以寫成:在沒有競爭條件的條件下更新Django
if (self.x == y):
self.x = z
self.save()
else:
raise Exception()
然而,有一個競爭條件。我想出了以下解決方案:
from django.db import transaction
with transaction.atomic():
if (self.x == y):
self.x = z
self.save()
else:
raise Exception()
但是這是安全的,有沒有更好的辦法?
首先,我想知道爲什麼你需要使用'transaction.atomic',因爲'select_for_update'應該鎖定行。但是,它僅鎖定在單個事務的範圍內,並且每個查詢都將是它自己的事務(如果使用自動提交),如[在此解釋](http://stackoverflow.com/a/17149748/2184571)所述。因此,你需要'transaction.atomic'包裝,對吧? –
@jluttine:是的,確切的。從文檔:「在自動提交模式下用'select_for_update()'評估查詢集...是一個'TransactionManagementError'錯誤,因爲在這種情況下行沒有被鎖定。」 –
實際上,有幾個問題:首先,不是'transaction.atomic'不必要的,因爲'get'後面的唯一事務是'save'並且沒有其他事務?其次,如果引發異常,是否釋放了'select_for_update'鎖定?在這種情況下,不會生成事務,因此鎖不會被釋放,或者是否? –