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'锁定?在这种情况下,不会生成事务,因此锁不会被释放,或者是否? –