一尘不染

django中计数器的原子增量

django

我正在尝试以原子方式在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,则应将函数包装在事务中并使增量成为原子。但这不起作用,并且计数器更新中存在竞争条件。如何使此代码成为线程安全的?


阅读 435

收藏
2020-04-02

共1个答案

一尘不染

Django 1.1的新功能

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

或使用F表达式:

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

请记住指定要更新的字段,否则您可能在模型的其他可能字段上遇到竞争条件!

2020-04-02