CQRS and Race : how to handle race requirements

437 views Asked by At

While there are articles saying that race conditions do not occur in business world, and it the solution that what we need to look, I am not sure it is the case.

I have a need of capacity and do event ticketing. When the demand for the event is high there are many concurrent bookingCommands that come in the same microsecond. The traditional way to do this is to use locking to prevent RACE conditions. Otherwise it ends up selling tickets for seats that are not available which is a strict business no-no.

Below table shows the sequence of steps that occur concurrently.

Time | Total Capacity | Consumed | Available | Customer1 | customer2

  1  |            100 | 99       |  1        |seat available?|  -
  2  |                |          |           |  apply        |  seat available ?
  3  |                |          |           |  event handle |  apply
  4  |                | 100      |   0       |  update state |  event handle
  5  |                | 101      |  -1       |               |  update state
1

There are 1 answers

2
b2zw2a On BEST ANSWER

If "selling tickets for seats that are not available is a strict business no-no." then model it this way. What this requirement tells you is that "selling/reserving a seat" and "number of seats available" should end up in the same transaction and be consistent. You can't take reservation and fire an event to change the number of available seats, it has to be in single transaction. This way when you try to decrease "number of seats available" (Time-5 from your table) you will receive optimistic concurrency exception, because someone modified it in the meantime. Then you can try to process it again and this time number of available seats has been exhausted so you can publish "application/reservation rejected" event and notify the user.

Project "a CQRS Journey" is something you should have a look at:

The reference implementation will be a conference management system that you will be able to easily deploy and run in your own environment. This will enable you to explore and experiment with a realistic application built following a CQRS-based approach.

Especially have a look at SeatsAvailability.MakeReservation and SeatsAvailabilityHandler.Handle(MakeSeatReservation command)