[elephant-devel] DB Transactions and UI

Ian Eslick eslick at csail.mit.edu
Thu Jun 28 16:51:42 UTC 2007


> What about the below situation:
>
> Assume there is list of open chairs of a cinema hall, user selects the
> chair that he wants to buy, if the transaction is short, (ie
> non-locking) and at the same time if another user buys that chair,
> who's the owner of the chair really?
>
> Application layer locking is painful to implement and adds several
> transient states. I've seen only a single approach  called "Namos"
> targetting these kinds of problems, unfortunately no implementations
> exist.

I'm not sure what you mean by transient states.  Application layer  
locking can mean many things.

I would propose for your scenario that each entry have a state so  
that the various low-level transactions working together provide a  
clean view of the world to the user.

Of course, ultimately, there is no magic that is going to solve all  
the variations of these kinds of problems.  Even short lived  
transactions require that you think carefully about your application- 
level policies and potential side effects.

In general I work from the user constraints and then try to figure  
out the most compact and simple way to express that process  
technically.  If you have a user process such as

1) Browse/search for seats
2) Select a seat
3) Commit a purchase of the seat

each of which may be separated by minutes, then we need to choose how  
to resolve conflicts where two users are looking at the same seats,  
selecting the same seats or buying the same seats.

If you resolve conflicts in case 1, you would have to make sure that  
only one user can look at a given seat at a time.  That requires that  
you somehow keep a user from seeing seats being looked at by another  
user.  At least in the BDB transaction lexicon, there is no good way  
to do this as other transactions would block on a locked seat, not  
ignore it.

You'll have to annotate the subset of seats being looked at by a  
given user, so you'd have transaction that read a list of seats and  
then marked them as unavailable.  Since this transaction is  
guaranteed to be atomic, users would never look at seats that another  
user was looking at.  This, of course, is too conservative for most  
cases where users are looking at a range of options, but it's  
probably ok if they are looking at one at a time.

If you resolve in case 3, users are probably going to be upset since  
they thought they had already committed to purchase and were just  
going through the financial steps.

So I'd use case 2 and a simple state machine, the rough design would be:

Seat object has a state field = { available, reserved, buying,  
sold }, a purchase record field and a timestamp field.

Browse/search - everyone can see everything that is 'available'.
	DB Transaction protect the read so only 'available' records are  
retrieved.
Select a seat - choose your seat and start purchase process
	DB Transaction:
	  1) check whether state is 'reserved' if so, abort txn and tell user
	  2) if not, set state to 'reserved'
	  3) set purchase record to a new transaction record
	  4) set timestamp
	If someone reserved before you, just tell the user that 'that seat  
is no longer available'
Purchase - Execute financial transaction
	DB Transaction:
           1) if state is 'available', abort and tell user that it  
took him/her too long to do xaction
	  2) else, set state to 'buying'
	Execute external payment transaction, on success...
	DB Transaction:
	  1) set state to 'purchased'
	else retry if not timed out, or make the seat available again and  
put user back into search mode
	
Maintenance -
	DB Transaction:
	  1) get all 'reserved' seats
	  2) if timestamp < current_time and  reset to 'available'	

This is an application policy that uses underlying DB transactions to  
maintain a coherent state of a seat record in the presence of  
concurrent users.  It allows users to build a simple mental model of  
seat availability that is easy to communicate.  I can't think of  
anyway this scenario could be implemented by a low-level DB with a  
single long-lived transaction.  I could imagine a policy abstraction  
for objects like this that make variations on this theme easy to  
manage.  Robert might have more to say on the topic.

It is, of course, entirely possible that I'm missing something.  This  
is not an area in which I have significant expertise.

Ian








More information about the elephant-devel mailing list