我对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)提供了事务隔离级别的一个很好的描述。也就是说,我更喜欢你的排锁想法,并且它仍然可以和上面的检查一样。 –