The Last Blue Mug

Suppose the mug shop has one blue mug left. Both replicas show a quantity of 1. Two shoppers, each with a cart containing that mug, place their orders at the same time, before the replicas exchange their changes. The load balancer sends one request to replica A and the other to replica B.

Each request uses the conditional update from the previous chapter: reduce the quantity by one only if at least one is available.

What happens Replica A Replica B
Before either purchase Quantity is 1 Quantity is 1
Each request checks its local stock Enough for one mug Enough for one mug
Each request reduces its local stock Quantity becomes 0 Quantity becomes 0
Each transaction finishes First order recorded Second order recorded

Each replica followed the rules we gave it. The stock check and reduction were atomic, and each transaction recorded an order and marked its cart as ordered. Neither replica ever stored a negative quantity. But Shopend accepted two purchases of the one remaining mug.

The conditional update protects competing requests that change the same stored stock value. Here, the requests changed separate copies of that value. A transaction on replica A does not make replica B aware of the purchase.

Copying afterward is too late

Suppose we copy the changes between the replicas after both purchases finish. Both stock values are already zero, so making those values agree does not reveal that we sold the mug twice. If we also copy the orders, both replicas will hold two accepted orders for one mug.

We could discover the problem and cancel one purchase, but that would change the behavior we promised. The requirement is to avoid accepting a purchase when there is not enough stock.

So we need to decide how the replicas coordinate changes before we let both accept purchases independently.

Coordinating the replicas

Replication introduces decisions that we did not have to make when duplicating the API instances:

  • Which replica may accept a write?
  • When do the other replicas receive it?
  • Which replica may answer a read?
  • What happens when a replica cannot be reached?