Trying to understand isolation levels better – using entity framework and sql server
What would be the recommended isolation level for the following scenario –
An online booking system say for flight tickets or event tickets
Scenario –
Let us assume the capacity of the event is 100 – the pseudocode is as follows
Begin transaction
If SeatCount < 100
SeatCount = SeatCount + 1
End transaction
EDIT – in response to the comment here is how my pseudeocode would look like in actual code. I don’t have the code and I am just looking to understand the scenario better. Let us say you have two tables “event” where you have two columns – “name, seatsbooked” and a table tickets where you have the individual ticket details.
bool tSuccess = false;
//this transactionscope resolves to serializable
using (TransactionScope transaction = new TransactionScope()
{
try{
if(objectcontext.event.SeatsBooked < 100)
{
objectcontext.event.SeatsBooked = objectcontext.event.SeatsBooked + 1;
ticket newTicket = new ticket{
};
objectcontext.tickets.AddObject(newTicket);
objectcontext.SaveChanges();
}
}
catch(Exception e)
{
//log and return
}
}
if (tSuccess)
{
bd.AcceptAllChanges();
}
In this scenario is it ok to assume that read committed or repeatable read would result in overbooking or lost updates since two transactions can compete for the same seat.
Is the recommended approach to go with serializable?
Repeatable read is required, serializable is not necessary. Repeatable read ensures that the update will see the same seat count as the previous select did.
Your
TransactionScopeneeds to span the entire logical unit of work, though. Not just the write.In raw SQL it would be more elegant to use
WITH (UPDLOCK, HOLDLOCK)but that is not available with EF.In case of a conflict, a deadlock will easily occur. Either retry the entire logical transaction or select with
UPDLOCK.UPDLOCKwill avoid that deadlock entirely.