Django中计数器的原子增量 [英] Atomic increment of a counter in django

查看:44
本文介绍了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中计数器的原子增量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆