Do I Need To Use Transactions In Google Appengine
Solution 1:
Have a look at optimistic concurrency control: http://en.wikipedia.org/wiki/Optimistic_concurrency_control
Solution 2:
You can check for the availability of the time slots in a given Court
, and write the corresponding Reservations
child entities only if their stat_time
don't conflict.
Here is how you would do it for 1 single reservation using a ancestor Query:
@ndb.transactionaldefmake_reservation(court_id, start_time):
court = Court(id=court_id)
existing = Reservation.query(Reservation.start_time == start_time,
ancestor=court.key).fetch(2, keys_only=True)
iflen(existing):
returnFalse, existing[0]
returnTrue, Reservation(start_time=start_time, parent=court.key).put()
Alternativly, if you make the slot part of the Reservation id, you can remove the query and construct the Reservation entity keys to check if they already exists:
@ndb.transactionaldefmake_reservations(court_id, slots):
court = Court(id=court_id)
rs = [Reservation(id=s, parent=court.key) for s in slots]
existing = ndb.get_multi(r.key for r in rs)
ifany(existing):
returnFalse, existing
returnTrue, ndb.put_multi(rs)
Solution 3:
I think you should always use transactions, but I don't think your concerns are best addressed by transactions.
I think you should implement a two-stage reservation system - which is what you see on most shopping bags and ticketing companies.
- Posting the form creates a "reservation request" , which blocks out the time(s) as "in someone else's shopping bag" for 5-15 minutes
- Users must submit again on an approval screen to confirm the times. You can give them the ability to update the conflicts on that screen too, and reset the 'reservation lock' on the timeslots as long as possible.
- A cronjob - or a faked one that is triggered by a request coming in at a certain window - clears out expired reservation locks and returns the times back to the pool of available slots.
Post a Comment for "Do I Need To Use Transactions In Google Appengine"