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中计数器的原子增量
基础教程推荐
- 由Python将MP3转换为MIDI(类型错误:无法加载插件:mtg-Melodia:Melodia) 2022-01-01
- numpy float:比算术运算中内置的慢 10 倍? 2022-01-01
- 将 x 轴刻度更改为自定义字符串 2022-01-01
- 用 Python 编写 Fortran 无格式文件 2022-01-01
- 与常规 dict 相比,Python manager.dict() 非常慢 2022-01-01
- 尝试制作WhatsApp机器人 2022-01-01
- pyserial - 可以从线程 a 写入串行端口,是否阻塞从线程 b 读取? 2022-01-01
- 使用生成器和迭代器时 Python 多循环失败 2022-01-01
- 在 Celery 工作人员中捕获 Heroku SIGTERM 以优雅地关 2022-01-01
- Discord.py 缺少必需的参数 2022-01-01
