Atomic increment of a counter in django(Django中计数器的原子增量)
问题描述
我正在尝试在 Django 中以原子方式递增一个简单的计数器.我的代码如下所示:
I'm trying to atomically increment a simple counter in Django. My code looks like this:
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,这应该将函数包装在事务中并使增量原子化.但它不起作用,并且计数器更新中存在竞争条件.如何使这段代码成为线程安全的?
If I understand Django correctly, this should wrap the function in a transaction and make the increment atomic. But it doesn't work and there is a race condition in the counter update. How can this code be made thread-safe?
推荐答案
使用 一个 F 表达式:
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,否则你可能会在模型的其他字段上遇到竞争条件.
Remember to specify update_fields, or you might encounter race conditions on other fields of the model.
关于比赛的说明使用F表达式避免的条件已添加到官方文档中.
A note on the race condition avoided by using F expressions has been added to the official documentation.
这篇关于Django中计数器的原子增量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Django中计数器的原子增量
- CTR 中的 AES 如何用于 Python 和 PyCrypto? 2022-01-01
- YouTube API v3 返回截断的观看记录 2022-01-01
- 计算测试数量的Python单元测试 2022-01-01
- 使用 Cython 将 Python 链接到共享库 2022-01-01
- 使用公司代理使Python3.x Slack(松弛客户端) 2022-01-01
- 我如何卸载 PyTorch? 2022-01-01
- 检查具有纬度和经度的地理点是否在 shapefile 中 2022-01-01
- 我如何透明地重定向一个Python导入? 2022-01-01
- 如何使用PYSPARK从Spark获得批次行 2022-01-01
- ";find_element_by_name(';name';)";和&QOOT;FIND_ELEMENT(BY NAME,';NAME';)";之间有什么区别? 2022-01-01
