Guide

Some resources are scarce and heavily contended. Concert seats, hotel rooms, warehouse stock and money in an account all fit that description. For these, a common pattern splits each step into a reservation followed by a confirmation. Nothing irreversible happens until every party has agreed.

Concept

A hold is a reversible claim on a resource that expires on its own. Holds let you check and reserve before you commit.

Try, confirm, cancel

Try-Confirm-Cancel (TCC) formalizes this. Each participant exposes three operations:

  1. Try. Check the business rules and reserve the resource, without consuming it. "Hold seat 14C for order o_123 for 10 minutes." "Authorize $40 on this card." A card authorization is a real-world hold.
  2. Confirm. Turn the reservation into the final change. "Mark seat 14C sold." "Capture the $40."
  3. Cancel. Release the reservation. "Release seat 14C." "Void the authorization."

The coordinator calls Try on every participant. If all succeed, it calls Confirm on all of them. If any fails, it calls Cancel on those that succeeded.

Walking through a checkout

Try      seat 14C  → held for order o_123, expires at 10:10
Try      card      → $40 authorized
Confirm  seat 14C  → sold
Confirm  card      → $40 captured

If the card step fails instead, the coordinator cancels the seat, which releases it for the next buyer.

Every hold has an expiry. If the coordinator disappears, the holds release themselves. That is the key improvement over 2PC, where a participant can hold locks until someone resolves the transaction by hand.

How TCC differs from 2PC

TCC looks like 2PC at the business level, but there are real differences:

  • Participants don't hold database locks between the phases. The reservation is a normal committed row.
  • The "prepared" state is visible, and it has a timeout.
  • Participants can be anything with an API, including third parties that offer holds.

Card payments already work this way: authorize, then capture or void. That is why e-commerce checkouts can be built on it. The ticket booking case study builds on seat holds with expiry.

Common mistakes

  • Holds without an expiry. A dead coordinator then leaves seats locked forever.
  • A Try that consumes the resource. A hold must be reversible, or Cancel has nothing to undo.
  • A Confirm that isn't idempotent. A retried confirm can capture money twice. See idempotency keys.

Check yourself

1. What makes TCC safer than 2PC when the coordinator dies? Holds expire, so the resource is released on its own. A 2PC participant can hold its locks until someone resolves the transaction.

2. Why must Try reserve the resource rather than consume it? Because a failed transaction must be able to cancel cleanly. A consumed resource can't be released.

Key takeaways

  • TCC splits each step into Try, Confirm and Cancel.
  • Holds are normal committed rows with expiry, not database locks held across calls.
  • Expiry lets the system recover when the coordinator fails.
  • Confirm and Cancel must be idempotent, because they are retried.

Further learning

Next, see how holds with expiry play out in a full system in the ticket booking case study.