0

I'm working with django-nonrel and django-rest-framework and I've got this view method who appends numbers into an array.

def add_number(self, request, *args, **kargs):
    row = self.get_object()                          # Gets the row from DB
    row.numbers.append(request.POST.get('number'))   # Modifies the column
    row.save()                                       # Save to DB
    serializer = self.get_serializer(row)
    return Response(serializer.data)

If another client attempts to add_number his number at the same concurrent time, Is it posible that one numbers does not remain stored?

Extra info

This is running in Google App Engine, with django-nonrel@1.5 and django-dbindexer, Google Cloud Datastore as database. Does @transaction.commit_on_success solve it? (I believe it doesn't)

mariowise
  • 2,167
  • 2
  • 21
  • 34
  • But are transactions web scale? Anyway, transactions won't solve this, because you're not acquiring a lock on the row you're editing. I'm not that familiar with NoSQL, but to prevent race conditions you generally need a lock-get-edit-save workflow, in a single transaction. At the moment you're definitely missing the lock. – knbk Jun 24 '15 at 15:37
  • 1
    (If you could use a single `UPDATE` statement instead, that would certainly avoid race conditions.) – knbk Jun 24 '15 at 15:41
  • Maybe this works for you http://stackoverflow.com/questions/1123200/how-to-lock-a-critical-section-in-django – Ale Jun 24 '15 at 15:42
  • Well there is no `update` where I can **append** into an array/column. There are some methods for *increment* or *decrement*. And **Ale**, this case works with `NoSQL` database, so I'm not sure if those solutions works on `Google App Engine`. Actually I've no Idea how to get Erlang working on GAE. – mariowise Jun 24 '15 at 21:22
  • I would suggest you look at CAS operations using memcache to create a lock. You don't suggest by what criteria/key you are using in the implementation of get_number that that will be important. You will possibly find transactions will solve the problem but django seems to abstract things a bit too much, and have never looked at django so can't comment further. – Tim Hoffman Jun 25 '15 at 11:23
  • Well here is what I've found.. Ussually transactions wont solve this problem, but in this case, the app is running over `Google App Engine` and the database is google's `Datastore`, where transactions actually solve this `race condition` problem. https://cloud.google.com/appengine/docs/python/datastore/transactions#Python_Uses_for_transactions – mariowise Jun 25 '15 at 12:05

0 Answers0