python - django中计数器的原子增量

标签 python django transactions race-condition

我试图在 Django 中自动增加一个简单的计数器。我的代码如下所示:

from models import Counter
from django.db import transaction

@transaction.commit_on_success
def increment_counter(name):
    counter = Counter.objects.get_or_create(name = name)[0]
    counter.count += 1
    counter.save()

如果我正确理解 Django,这应该将函数包装在事务中并使增量原子化。但它不起作用,并且计数器更新中存在竞争条件。如何使这段代码成为线程安全的?

最佳答案

使用 an F expression :

from django.db.models import F

update() 中:

Counter.objects.get_or_create(name=name)
Counter.objects.filter(name=name).update(count=F("count") + 1)

或在对象实例上:

counter, _ = Counter.objects.get_or_create(name=name)
counter.count = F("count") + 1
counter.save(update_fields=["count"])

记得指定 update_fields,否则你可能会在模型的其他字段上遇到竞争条件。

关于 race condition avoided by using F expressions 的注释已添加到官方文档中。

关于python - django中计数器的原子增量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1598932/

相关文章:

python - Django 可插拔动态导航应用程序

django - 每个存储库的 GitHub 问题 ID 从 1 开始,我如何在 Django 中复制它?

c# - RepeatableRead 似乎没有锁定读取

java - Postgresql:在同一事务中读取未提交的数据

python - 这个嵌套 for 循环的时间复杂度是多少?

python - 如何扩展 Django Form 类?

带有变量的 Django url 模板标签

c# - ASP.Net C# - MySQLTransaction 多次插入

Python 脚本使用 Windows 调度程序意外终止

python - SQL 数据库是否比大型 Pandas 数据框的内存/性能效率更高?