> Finally, nested transactions can run afoul of correctness in distributed apps. In fact, the idea of multi-component transactions in client code really evokes the idea of a bull in a china shop. As long as all is well and the transaction is due to commit, the idea somewhat makes sense. However, what happens when the database (and not the client) decides the transaction is un-committable and must be aborted, for example because of a serializability conflict or a node restarting for maintenance? It is not just the database state that must be rolled back; all the possible side effects performed by the components holding the transaction must also be rolled back. Think about payment transactions. Think about email notifications. For one, the programmer is unlikely to think about this properly before the app is deployed. Also, as the number of components involved grows, the chance they are collectively performing unabortable external side effects (logging, payments, notification emails or SMS, REST queries to external HTTP APIs, etc) increases dramatically.
Is this really an argument against nested transactions? It seems like an argument against all kinds of transactions that are linked to irreversible side effects, regardless of whether any are nested.
> Nowadays, such tight coupling has a bad rep. This is because two additional decades of software engineering have taught us that implicit global state really, really does not play well with distributed services where some components may fail even as part of normal load. It makes it hard to fail over a component gracefully by transferring its responsibility to a hot spare. It makes it hard to reason about the current state of a component and troubleshoot it by just looking at the log of its inputs and outputs.
This is convincing, but I would love to know what the author (or others) think the better alternative is, which solves the hot spare and "normal load failure" problems. Is it highly-available message queues? (And assume they never fail or all fail at once, but never fail piecemeal because that would cause half-updated state?) Is it (distributed/microservices) application code stuck in (distributed) retry loops when there are failures, to get its job done without half-updated state?
> Additionally, nested transactions can amplify performance anomalies. The row locks established by a large transaction whose latency extends across multiple components/services are more likely to incur transaction conflicts which, at best, increase the average latency of queries and, at worse, increase the error rate quadratically with the current query load.
Is this not a CockroachDB-specific performance limitation, rather than an argument against nested transactions per se?