database - Django:避免数据库和 ORM 中的 ABA 场景

标签 database django algorithm

我有一种情况需要更新候选人的选票。

公民可以投票给这个候选人,每个候选人可以投一票以上。即一个人可以投 5 票,而另一个人可以投 2 票。在这种情况下,该候选人应获得 7 票。

现在,我使用 Django。这是伪代码的样子

votes = candidate.votes 
vote += citizen.vote 

这里的问题,如您所见,是一个竞争条件,在这种情况下,候选人的选票可能会被另一个公民的选票覆盖,后者之前进行了选择并现在设置。

如何使用像 Django 这样的 ORM 来避免这种情况?

最佳答案

如果这纯粹是一个算术表达式,那么 Django 有一个很好的 API,叫做 F expressions


根据现有字段更新属性

有时您需要对字段执行简单的算术任务,例如递增或递减当前值。实现这一目标的明显方法是执行以下操作:

>>> product = Product.objects.get(name='Venezuelan Beaver Cheese')
>>> product.number_sold += 1
>>> product.save()

如果从数据库中检索到的旧 number_sold 值为 10,则值 11 将被写回数据库。

这可以通过表达相对于原始字段值的更新来稍微优化,而不是作为新值的显式赋值。 Django 提供 F() 表达式作为执行这种相对更新的方式。使用 F() 表达式,前面的示例将表示为:

>>> from django.db.models import F
>>> product = Product.objects.get(name='Venezuelan Beaver Cheese')
>>> product.number_sold = F('number_sold') + 1
>>> product.save()

此方法不使用数据库中的初始值。相反,它使数据库根据执行 save() 时的当前值进行更新。

保存对象后,您必须重新加载对象才能访问应用于更新字段的实际值:

>>> product = Products.objects.get(pk=product.pk)
>>> print product.number_sold
42

关于database - Django:避免数据库和 ORM 中的 ABA 场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8353255/

相关文章:

c++ - 按特定顺序迭代 NxN 矩阵的上三角

algorithm - 如何找到给定范围内可被给定值整除的值的数量?

python - 使用 Django South 处理大型项目的迁移是否安全

python - django查询检索以父名称为键的子值字典?

数据库模式 : What's the standard way for manually sorting a table?

c# - 使用 Linq to sql 将 List<String> 插入到 ntext 字段

python - 在 django 中安全地从 POST 或 GET 检索数据

c++ - Rabin-Karp 字符串匹配不匹配

java - JPA 将属性存储为行

java - 如何计算 Hibernate 查询语言中的行数?