HRD transaction that involves an RPC or How do Transactions work on GAE?

2 views
Skip to first unread message

dragonx via StackOverflow

unread,
Aug 3, 2012, 12:48:15 PM8/3/12
to google-appengin...@googlegroups.com

This will be a bit of a combo question, mostly because I'd like to get some more background info.

The main question:

I'm trying to do a transaction that involves an RPC call to another REST service, that will update some remote data. For example, say the RPC call tells the remote server that I purchased something. In nonfunctional python pseudocode it'll be something like:

def txn_purchase():
    a = ModelA.objects.get(blah)
    httpresult = HttpPurchaseRPC(url, a.foo)
    a.receipt = httpresult.get_receipt() # This raises an error if the request fails
    a.save()

db.run_in_transaction(txn_purchase)

I'm pretty sure that transactions only ensure datastore consistency (so in this case, entity a will be consistent), and it doesn't ensure consistency with the RPC. Is it possible to build something on top of this that ensures consistency with the RPC as well?

To me it looks like I'll have a potential problem case if the RPC succeeds, but the datastore transaction failed to save. How do I get around this?

The hazy concept in my mind is to implement a 2-stage purchase:

  1. Do a prepurchase phase where I create entity A in a transaction and set a prepurchase flag.
  2. Do a purchase phase where I run the purchase transaction and update A if successful. Clear the prepurchase flag.
  3. Have a "fix-it" cron job that runs and scans for stale entities with a pre-purchase flag, and use another RPC to check whether those purchases have actually gone through.

Is this the "best practice" way to do it, or is there something better?

Background questions on transactions:

  • Do the transaction functions run on the frontend with the rest of the code, or is it somehow magically run on the datastore backend?
  • If the frontend that a transaction is running on dies in the middle of the transaction (ie timeout), will the transaction be retried anywhere? Or the transaction simply doesn't happen?

Thanks!



Please DO NOT REPLY directly to this email but go to StackOverflow:
http://stackoverflow.com/questions/11799905/hrd-transaction-that-involves-an-rpc-or-how-do-transactions-work-on-gae

Daniel Roseman via StackOverflow

unread,
Aug 3, 2012, 1:03:15 PM8/3/12
to google-appengin...@googlegroups.com

You sort of have the right idea here: the way you should do this is to farm out the RPC to a separate deferred task. Tasks that are enqueued within a transaction can have a flag set to ensure they only get enqueued if the transaction succeeds.

There's no magic backend that runs transactions. And they're not retried automatically: again, unless they are part of a task, as tasks are retried until they return successfully.



Please DO NOT REPLY directly to this email but go to StackOverflow:
http://stackoverflow.com/questions/11799905/hrd-transaction-that-involves-an-rpc-or-how-do-transactions-work-on-gae/11800131#11800131

Daniel Roseman via StackOverflow

unread,
Aug 3, 2012, 1:23:18 PM8/3/12
to google-appengin...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages