我對Django相當陌生,而且我不確定如何管理併發。確保保存模型時的原子性
我正在構建預留設備的應用程序。 我有一個ManytomanyField的設備預訂模型。 當我創建新的預訂時,我必須確保所有設備都可用。 我的代碼的第一個版本不關心併發:
def validate_reservation(keys, begin, end):
eqpts = Equipment.objects.filter(pk__in=keys)
if all(eqpt.is_available(begin, end) for eqpt in eqpts):
res = Reservation(eqpts, begin, end)
res.save()
return True
else:
return False
的is_available方法檢查是否存在已經是對給定日期的任何保留:
def is_available(self, begin, end):
return not self.reservations.filter(begin__lte=end, end__gte=begin).exists()
的問題是,兩個用戶運行如果在第二次檢查設備的可用性後第一次保存他的預訂,則此代碼可能會產生衝突預訂。
我相信我能解決交易問題,所以這次我什麼,我想出了:
def validate_reservation(keys, begin, end):
with transaction.atomic():
eqpts = Equipment.objects.select_for_update().filter(pk__in=keys)
if all(eqpt.is_available(begin, end) for eqpt in eqpts):
res = Reservation(eqpts, begin, end)
res.save()
return True
else:
return False
這是否有預期的行爲? 如何知道交易是否失敗並通知用戶?
有沒有不同的更好的方法?
感謝您的回答,並且更好的檢查! 我的鎖仍然適合您的支票,對不對?你能告訴我更多關於你提到的其他事務隔離級別嗎? – Atn
@An:你沒有提到你的數據庫,但[PostgreSQL文檔](http://www.postgresql.org/docs/9.4/static/transaction-iso.html)提供了事務隔離級別的一個很好的描述。也就是說,我更喜歡你的排鎖想法,並且它仍然可以和上面的檢查一樣。 –