views:

36

answers:

2

Hello, what would be the best way to create mechanism that ensures that for example:

Two people won't buy same item at the same time in auction based on GAE application using BigTable?

If someone could enlighten me with "under the hood" kind of description I would be grateful.

A: 

In the transaction, check that the auction is still open, for example by checking that the winner field is not set, and if so, set winner to the current user.

Since it happens in a transaction, there is no chance that the item will be snatched up mid-transaction. If another user tries to win the auction at the same instant, they will not be able to write to the item until the first user is done, at which point the "is it still available?" check will fail.

Jason Hall
+3  A: 

Such a transaction is quite simple to implement with AppEngine. The key is the run_in_transaction method:

class AuctionItem(db.Model):
    sold = db.BooleanProperty()
    purchaser = db.UserProperty()

def buy(self, buyer):
    def buy_txn():
        sale_success = False
        if self.sold == False:
            self.sold = True
            self.purchaser = buyer
            self.put()
            sale_success = True
        return sale_success

    success = db.run_in_transaction(buy_txn, buyer)
    return success
Adam Crossland
I think I would find it cleaner to only check/update one field, in this case `purchaser`, since sold is `False` iff purchaser is `None`, and vice versa. Personal preference though, I suppose.
Jason Hall
In your example, when does the get() on the AuctionItem happen? Doesn't it need to happen within the transaction?
cope360