Book Deep Read · Database Internals · Chapter 13

Distributed Transactions

Database Internals · Ch 13 · Alex Petrov · 2019

中文 →

What is this chapter about?

You tap "transfer." Money leaves your account and lands in someone else's. If only one of those two halves happens, that is a disaster. A single database solved this problem decades ago — this chapter asks the harder version: when the two accounts do not even live on the same machine, how do you guarantee "either both or neither"? That is a distributed transaction.

Start with something odd

Picture three people in three cities who must sign the same contract, and it has to be all three or none, and they can only use the phone. The usual trick is to appoint a convener who makes two rounds. Round one: ask each person "can you sign?" — and note that answering "yes" means picking up the pen and holding your slot, with no backing out. Round two: once every answer is in, tell each of them "sign."

The odd part sits between the rounds. After collecting every "yes" but before telling anyone anything, the convener drops their phone in a lake. The other two dare not sign (what if the convener actually decided to call it off?) and dare not walk away (what if someone already signed?). All they can do is hold the pen, occupy the room, and wait.

Why the old world found this hard

This is not clumsiness; it is unavoidable. From where the other two stand, "the convener never decided" looks exactly like "the convener decided and I never heard." While the second possibility is live, nobody dares call it themselves. So the two-round scheme has a hard flaw: it guarantees you never get it wrong, but not that you keep moving. In a database, "holding the pen" means those rows are locked — nobody can read or write them — and a convener's restart can take minutes.

Three different ways out

Does one more phone call help? A little: the convener first announces "I am about to have you sign," and after that, anyone who hears nothing further signs by default. But if the phone line is cut in half, each side acts on its default and you can end up half-signed, half-cancelled — worse than being stuck. The three moves that actually work do not improve those two rounds; they change the foundation:

① Take a number first, act second. Stop asking "can you?" Instead, put everything everyone wants to do into one agreed numbered order, and let each person work the list. Same order, same rules, same result — no negotiation needed.

② More than one convener. Let a small group hold that role jointly, so a decision is remembered by several people at once; one phone in the lake changes nothing.

③ Write "who signed" onto the contract itself. Agree that one particular page is decisive: once it is signed, the whole thing is in force. Anyone who later opens the binder tidies the other pages up or crosses them out — no convener has to stay in the room.

How to choose

All three charge tuition: the take-a-number approach demands that you declare everything you intend to do up front, with no improvising mid-way; the many-conveners approach needs very accurate clocks and more expensive machine rooms. Which is why engineering often has a better fourth answer: first check whether this really has to be one transaction at all.

One sentence to remember

Getting "all or nothing" across machines is hard because everyone must promise not to back out before any decision can be made — and in the sliver between that promise and the decision arriving, one fallen convener leaves everybody holding locks. Every later answer changes the foundation instead: take a number, make the convener a group, write the state into the data itself — or just do not open the transaction.

Want the actual 2PC / 3PC protocols, the Calvin-versus-Spanner split, and the diagrams? → Switch to the deep read