>> 1) retrieve the current_high_bid field of the Auction object
>> 2) compare it with the new_bid
>> 3) if the new bid is higher than current_high_bid, I update
>> current_high_bid to the value of the new_bid.
>>
>> but there's a (slight) chance that between steps (1) and (3) a
>> different user could've submitted an even higher bid which then become
>> the current_high_bid. In that case step 3 should not proceed. What can
>> I do to make sure such a situation does not arise?
> 
> For now, you can write custom SQL (consider this pseudo-code rather  
> than a drop-in replacement):
> 
>       """ Be sure this all runs inside a single transaction!  Use the  
> appropriate middleware or
>           decorators... """
>       cursor = connection.cursor()
>       cursor.execute("SELECT high_bid FROM auctionapp_auction WHERE id=%s  
> FOR UPDATE", [auction.id])
>           """ Until this SELECT, other users could have modified the high  
> bid, so do not trust the
>               in-memory copy. """
>       returned_rows = cursor.fetchall()
>       high_bid = returned_rows[0][0]
>       if new_bid > high_bid:
>           auction.high_bid = new_bid
>           auction.save()


If you are going to drop to raw SQL, you can let SQL handle the 
atomicity:

   UPDATE auction SET
     current_high_bid = %(new_bid)f
   WHERE id = %(auction_id)i
     AND %(new_bid)f > current_high_bid

If the new_bid is based on data in another table of 
bid-histories, you can use something like

   UPDATE auction SET
     current_high_bid = (
         SELECT Max(bid)
         FROM Bids
         WHERE auction_id = %(auction_id)s
         )
   WHERE id = %(auction_id)i
     AND (
         SELECT Max(bid)
         FROM Bids
         WHERE auction_id = %(auction_id)s
         ) > current_high_bid

Adjust for table-names and field-names.  It should be fairly 
portable SQL, working across all of the big 3 Django databases 
(sqlite, postgres, and recent versions of mysql that support 
sub-selects...it also happens to work in SQL Server, FWIW)

-tim




--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to