Why cross-service ACID transactions are difficult
coreadvancedA single database can give ACID guarantees (atomicity, consistency, isolation, durability) across multiple writes within that one database, because it controls the locking, logging and commit process for everything it manages. A workflow spanning multiple independent services, each with its own database, has no single component in that position — no one process can atomically lock rows across two different databases, no one process can guarantee both writes commit or both roll back together, because each database only knows how to be ACID with itself, not in coordination with another database it has never heard of.
Think of it as
A single restaurant kitchen can guarantee that an order either fully comes out together or gets fully cancelled — one head chef coordinates everything happening at every station, so "the burger is ready but the fries are not" simply is not allowed to reach the table. Now imagine an order that needs a dish from a completely separate restaurant across town, with its own kitchen, its own staff, and no shared coordination. There is no single head chef who can force both kitchens to either both finish or both cancel together — the best you can do is have someone run between them relaying messages, and there is always a window where one kitchen has finished and the other has not, with no way to instantly and atomically force agreement across two places that were never designed to coordinate.
What we're doing: Show a two-service order flow where a naive sequential approach leaves the system in a genuinely inconsistent state with no database-level mechanism to prevent it.
- 9
- Nothing about this step is wrong on its own — the Orders database's own ACID guarantee is fully intact.
- 14
- This is the actual inconsistency: it lives BETWEEN two databases, in a space no single database's transaction mechanism was ever designed to cover.
Why this works: This is the precise, structural reason cross-service ACID is hard — the inconsistency does not come from either database failing to be ACID, it comes from there being no larger transaction boundary that spans both of them at all.
Assuming careful sequential ordering of writes is equivalent to atomicity
Wrong
Better
What you see: A "consistent by convention" cross-service write order works fine in testing and under normal conditions, then produces a real orphaned record the first time the second service is briefly unreachable in production — the specific failure the fixed ordering never actually protected against, only made slightly more predictable in shape.
Why: A fixed write order determines which side fails first when something goes wrong, but does nothing to prevent that failure from happening or to undo the first write once the second one fails — true atomicity requires an explicit mechanism to detect the partial failure and either complete or reverse it, which sequential ordering alone does not provide.
- INSERT order — Orders service, own DB
- leads to Order committed (succeeds)
- Order committed — fully consistent, alone
- on error, leads to UPDATE inventory (then)
- UPDATE inventory — briefly unreachable
What a single database's ACID guarantee covers vs a cross-service operation
Remember: A single database's ACID guarantee only covers what it directly manages — there is no built-in mechanism for making a write in one database part of the same atomic, isolated unit as a write in a completely separate database. The inconsistency risk lives in the space between services, which no single database's own transaction boundary was ever designed to cover.
See also: two phase commit · preferring sagas and compensation · at most least exactly once

