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中计数器的原子增量
基础教程推荐
- 对多索引数据帧的列进行排序 2022-01-01
- 在 Python 中将货币解析为数字 2022-01-01
- matplotlib 设置 yaxis 标签大小 2022-01-01
- 比较两个文本文件以找出差异并将它们输出到新的文本文件 2022-01-01
- Python,确定字符串是否应转换为 Int 或 Float 2022-01-01
- kivy 应用程序中的一个简单网页作为小部件 2022-01-01
- Kivy 使用 opencv.调整图像大小 2022-01-01
- Python 中是否有任何支持将长字符串转储为块文字或折叠块的 yaml 库? 2022-01-01
- 在 Django Admin 中使用内联 OneToOneField 2022-01-01
- 究竟什么是“容器"?在蟒蛇?(以及所有的 python 容器类型是什么?) 2022-01-01
