Atomic increment of a counter in 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()

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?

-------------Problems Reply------------

New in Django 1.1

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

or

counter = Counter.objects.get_or_create(name = name)
counter.count = F('count') +1
counter.save()

In Django 1.4 there is support for SELECT ... FOR UPDATE clauses, using database locks to make sure no data is accesses concurrently by mistake.

Keeping it simple and building on @Oduvan's answer:

counter, created = Counter.objects.get_or_create(name = name,
defaults={'count':1})
if not created:
counter.count = F('count') +1
counter.save()

The advantage here is that if the object was created in the first statement, you don't have to do any further updates.

Django 1.7

from django.db.models import F

counter, created = Counter.objects.get_or_create(name = name)
counter.count = F('count') +1
counter.save()

Or if you just want a counter and not a persistent object you can use itertools counter which is implemented in C. The GIL will provide the safety needed.

--Sai

Category:python Views:10 Time:2009-10-21

Related post

  • Increment Page Hit Count in Django 2009-03-07

    I have a table with an IntegerField (hit_count), and when a page is visited (for example, http://site/page/3) I want record ID 3's hit_count column in the database to increment by 1. The query should be like: update table set hit_count = hit_count +

  • Calling a stored procedure in parallel to increase a counter and ensure atomic increments 2011-04-01

    I'm creating a stored procedure which can increment the value of a counter and return if that invocation was responsible for reaching the MaxValue. The tricky part is this procedure will be call quickly and in parallel from different threads and diff

  • Atomic increment on mac OS X 2010-01-23

    I have googled for atomic increment and decrement operators on Mac OS X and found "OSAtomic.h", but it seems you can only use this in kernel space. Jeremy Friesner pointed me at a cross-platform atomic counter in which they use assembly or mutex on O

  • Can I do an atomic increment in Rails 2.3 without dropping down to SQL? 2011-02-02

    We have some often-hit code in our app that increments a column, like so: if (r = customer.find_or_generate_reminder) r.counter += 1 r.save! end We're getting lock wait timeouts, so I'm thinking about making this an atomic operation. Naively, what I

  • How to handle integer overflows with atomic increment and compare-and-swap operations? 2011-09-13

    I am writing a bit of code that implements an (unsigned) integer counter. It is used from an arbitrary number of threads. A thread should get a unique value every time until overflow. If integer type range is overflown, zero should be returned. I hav

  • global counter in Django Application? 2009-09-25

    I was wondering if there is "global counter" in Django application, like the way I store "global counter" in Servlet Context scope in Tomcat. something like getServletContext().getAttribute("counter"); counter++; --------------Solutions-------------

  • Implement atomic increment using atomic swap? 2009-11-11

    Suppose I'm writing (assembly) code for a CPU whose only atomic operation is an unconditional swap -- no LL/SC, no compare-and-swap, just plain swap. (An ARM9 would be an example of such a beast.) Is there a way to perform atomic increment/decrement

  • Atomic Increment & Fetch 2010-03-01

    I'm looking for a way to atomically increment a short, and then return that value. I need to do this both in kernel mode and in user mode, so it's in C, under Linux, on Intel 32bit architecture. Unfortunately, due to speed requirements, a mutex lock

  • How to do atomic increment/decrement with Elixir/SQLAlchemy 2010-11-12

    I'd like to increment (or decrement) a score field in an Elixir entity: class Posting(Entity): score = Field(Integer, PassiveDefault(text('0'))) def upvote(self): self.score = self.score + 1 However, this doesn't work reliably with concurrent calls t

  • Does IUnknown::QueryInterface() increment the reference count? 2011-09-11

    If I have an IUnknown *ptr, do I need to call Release() on every interface I obtain through ptr->QueryInterface(), in addition to calling ptr->Release() when I'm done with ptr? I used to think that the answer is "Yes", but this quote from MSDN

  • multiplatform atomic increment 2011-11-03

    Until std::atomic is available, what is the multiplatform (windows & linux) way of atomically increment a variable ? I am currently use boost::detail::atomic_count but it's in boost::detail namespace and I don't know if it's safe to use. --------

  • Atomic Increment Performance in SMP systems 2011-11-23

    I am interested in knowing which one the following methods of incrementing a global counter in the kernel will be most optimal in SMP systems? By optimal, I mean less amount of time taken as well as less CPU cycles spent. mutex_enter(mutex) counter++

  • Pig + Hbase Atomic Increment Column Values 2012-03-06

    I am trying to read in a Hbase atomic increment column into Pig and have access to it as Long value. However, the column value uses Hbases Hex like structure: \x00\x00\x00\x00\x00\x00\x00\x01 Does anyone know of a method to convert that in Pig to bec

  • In MS SQL Server, is there a way to "atomically" increment a column being used as a counter? 2008-10-10

    Assuming a Read Committed Snapshot transaction isolation setting, is the following statement "atomic" in the sense that you won't ever "lose" a concurrent increment? update mytable set counter = counter + 1 I would assume that in the general case, wh

  • What is the correct way to atomically increment a counter in App Engine? 2011-11-08

    I am using Java on Google App Engine and I am most familiar with the JDO datastore interface. I am trying to implement a simple download counter which stores its data in the App Engine datastore. I am only expecting a few thousands downloads/month so

  • accurate page view count in Django 2009-05-10

    What is a good approach to keeping accurate counts of how many times a page has been viewed? I'm using Django. Specifically, I don't want refreshing the page to up the count. --------------Solutions------------- As far as I'm aware, no browsers out t

  • Spam proof hit counter in Django 2009-07-31

    I already looked at the most popular Django hit counter solutions and none of them seem to solve the issue of spamming the refresh button. Do I really have to log the IP of every visitor to keep them from artificially boosting page view counts by spa

  • Atomically incrementing counters stored in ConcurrentHashMap 2010-07-26

    I would like to collect some metrics from various places in a web app. To keep it simple, all these will be counters and therefore the only modifier operation is to increment them by 1. The increments will be concurrent and often. The reads (dumping

  • SQL atomic increment and locking strategies - is this safe? 2010-09-29

    I have a question about SQL and locking strategies. As an example, suppose I have a view counter for the images on my website. If I have a sproc or similar to perform the following statements: START TRANSACTION; UPDATE images SET counter=counter+1 WH

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.194 (s). 11 q(s)