1

I am currently developing a google app engine app using the django non-rel web framework. I have a method which transfers money from one account to the other, it is very simple. When I run it on my local server using a debugger, it works just fine and transfers all the money correctly. However, when I run it remotely on app engine, I end up with strange negative values. The crux of the method is:

pubAccount.secondary_money = pubAccount.secondary_money + transaction.money
pubAccount.money = pubAccount.money - transaction.money

After extensive research I found that this could be due to the fact I am not using transactions meaning the transfer is in no way atomic, thus race conditions can occur. But django non-rel does not support transactions properly, and the parts it does support is not directly supported by app engine, and from what I've found, anything supported by python-app engine toolkit, is not supported by django non-rel.

so can anyone tell me how I can get transactions working on app engine with django non-rel!? Someone must have got it working out there!

Ali Afshar
  • 40,967
  • 12
  • 95
  • 109
user1830568
  • 495
  • 1
  • 7
  • 12

1 Answers1

1

Simple, use db.run_in_transaction()

Edit:

If it helps, here's the branches I use, running django-1.4, with ancestor query support.

https://github.com/dragonx/djangoappengine.git -> django-1.4 branch
https://github.com/dragonx/django-1.4.git -> 1.4-nonrel branch
https://github.com/dragonx/djangotoolbox.git -> features/django-1.4 branch
https://github.com/dragonx/django-dbindexer.git -> develop branch (although the 1.4wip branch looks better)
dragonx
  • 14,963
  • 27
  • 44
  • I tried this but I got: Only ancestor queries are allowed inside transactions. I did some searching but all examples using db.run_in_transaction() seem to use a 'key', which I assume has something to do with how big table works? – user1830568 Nov 16 '12 at 21:21
  • http://stackoverflow.com/questions/5552671/using-transactions-on-django-appengine – user1830568 Nov 16 '12 at 21:30
  • 1
    Ah good point. If you only have a few entities, you can use cross-group (XG) transactions. Otherwise, yes, you need ancestor queries. I did integrate aburgel's changes for ancestor queries. – dragonx Nov 17 '12 at 03:31
  • thanks, cross-group transactions was just what I needed. I also had to remove a couple of 'get' queries from within the transaction as: 'Only ancestor queries are allowed inside transactions' – user1830568 Nov 19 '12 at 18:05
  • I'd recommend a careful analysis of your datastore structure. A XG transaction might work for now, but you might be screwed if you need more than the XG transaction entity limit (I think it's 5 entities). In that case you'd have to use ancestor queries, and it's a lot of work to restructure your data. – dragonx Nov 19 '12 at 20:01
  • Where is `from google.appengine.ext import db` ?? I have `djangoappengine` (`django-nonrel`) and `dbindexer` (`django-dbindexer`) non of those packages has the `transaction` method. – mariowise Jun 24 '15 at 01:47