The Return of ACID — Why Agents Make Strong Transactions Non-Negotiable

Sagas and eventual consistency were designed for bounded failure modes. Non-deterministic agents force us to re-examine transaction boundaries.

The previous articles in this series have established two uncomfortable facts. Agents bypass the application layer, removing the business rules, validation logic, and authorisation controls that lived there. And when agents write, the damage is structural, cumulative, and often silent — visible only after it has propagated well beyond the point of origin. Both of those problems operate at the level of individual operations.

This article examines something more fundamental: what happens to the transaction itself.


A Problem We Decided Not to Solve

It is worth being precise about the history, because the conventional account flattens it. ACID — atomicity, consistency, isolation, durability — was not abandoned because it failed. It was set aside because enforcing it across distributed systems carried a cost that the industry, at a particular moment, decided was not worth paying. That is a different thing.

The pattern that replaced it is the saga. Rather than enforcing a single atomic transaction across multiple services or databases, a saga sequences a series of local transactions, each of which commits independently. If a step fails, compensating transactions run in reverse to undo what has already been committed. The design is elegant and, under the right conditions, it works well. The reason it works is precise: the failure conditions are anticipated and bounded. A saga designer defines, in advance, a compensating transaction for each step — what “undo” looks like if payment fails, if inventory cannot be reserved, if the downstream service is unavailable. The failure space is finite, known, and planned for.

What drove the widespread adoption of this pattern was not exotic distributed infrastructure. It was microservices. When a single logical system — an e-commerce platform, an HR application, an insurance claims processor — is decomposed into independently deployed services, each owning its own data store, you no longer have a single transaction boundary even within that system. The order service, the inventory service, and the payment service represent one business operation and three transaction boundaries. Sagas emerged as the standard answer to a problem that microservices created by design, and they spread widely for good reason. They are a sound pattern for the failure conditions they were designed to handle.


What Agents Do to the Failure Space

The saga pattern rests on a single structural assumption: the set of failure conditions is known when the compensating transactions are written.

Agents break this assumption. Not because they are more likely to fail, but because they can fail in ways that were never modelled when the saga was designed. An agent executing a multi-step workflow may complete three of four steps, receive a revised instruction mid-flight, and resume from a point that does not correspond to any state the saga anticipated. It may write data that is semantically incorrect — a plausible value that passes every structural check and triggers no failure condition — leaving the saga with nothing to compensate because, as far as the system is concerned, nothing went wrong. It may invoke operations out of sequence because its reasoning about the task differs from the sequence the saga assumed.

A saga compensates for predictable failures in a predictable system. The failure space of a non-deterministic agent is not predictable and not bounded. You can enumerate the ways a payment service might fail; you cannot enumerate the ways a reasoning system might produce a state the saga was not designed to handle. The compensating transactions, however carefully written, will not cover the ground they need to cover.


The Consistency Window Becomes an Error Budget

Eventual consistency carries an implicit assumption that is easy to overlook: the window of inconsistency — the period between one local transaction committing and the saga resolving to a settled state — is short, and the consequences of acting on data during that window are limited. The pattern was designed with this assumption baked in.

The clearest analogy is the cheque clearing system. When a cheque is written, there is a float period: the funds have left the payer’s account in one sense and have not yet arrived in the payee’s account in another. Banks absorbed this because the float was short, operations against it were limited, and reconciliation processes caught discrepancies before they compounded. Now consider an automated system making thousands of decisions against both accounts simultaneously during that float, with no reconciliation process fast enough to keep pace. The float period stops being a payment mechanism and becomes an error budget — a window during which autonomous decisions are made on data that does not yet reflect reality.

Agents do not account for the consistency window. They will query state during an in-progress saga and act on what the database returns, without any awareness that the data reflects a transaction in flight rather than a settled outcome. They will make decisions, trigger further operations, and write results — all against a state that has not yet resolved. By the time the saga completes, the downstream consequences may have propagated several steps further, each built on the same unstable foundation.

I saw a sharp version of this problem in a core banking programme. The design split regions across separate databases, with in-memory databases used for speed and event-based communication between regions to support cross-region transactions. On paper, it was an attractive architecture. Each region could scale independently. The databases could be replicated for disaster recovery. The event stream connected the regions without forcing every operation through one central bottleneck.

The difficulty was not that any one technology was unreliable. The databases behaved like databases. The stream behaved like a stream. The problem was the boundary between them. A cross-region transaction could be committed in one regional database, placed onto the event stream, and not yet consumed by the other region. In normal operation that window might be small. In a disaster recovery scenario it became critical.

Failing over the databases was not enough. The in-flight events had to fail over as part of the same logical transaction, because the real transaction was not database one, or the stream, or database two. It was the whole path: database one to event to database two.

That was the hard part. The stream could carry events reliably, but it did not make the database commit, the event handoff, and the second database update one indivisible transaction. The programme could not fully mitigate that gap without pulling the event state itself into an ACID boundary. The system never went live.

That experience is why I am sceptical of treating orchestration as a substitute for transactionality. The uncomfortable question is not whether the components are individually reliable. It is where the complete transaction actually lives.


Where Does the Transaction Belong?

The orchestration layer that manages agents has no transactional semantics. It can sequence operations, retry on failure, and route between services — but it cannot enforce atomicity, and it has no visibility into the committed state of the databases its agents are writing to. Placing transactional responsibility there is not an architectural decision; it is an absence of one.

The agent itself is an even less credible guarantor. Asking a non-deterministic reasoning system to manage its own transactional integrity — to know what constitutes a complete operation, detect its own partial states, and execute reliable compensation — is precisely the wrong model for the problem. The agent’s non-determinism is the source of the failure modes we cannot anticipate. It cannot also be the system responsible for recovering from them.

The database management system is the only layer that has the machinery to enforce transactional guarantees: atomicity, isolation, durable commit. These are not properties that can be approximated at a higher layer; they require the DBMS to enforce them at the point of write. The architectural direction of the past decade moved transactional logic progressively away from the database and toward the application and orchestration layers. Agents make the case for reversing that direction — not out of nostalgia, but because the alternative is non-deterministic actors operating without a net.


Revisiting Distributed Transactions

The tools for enforcing transactional guarantees across database boundaries have existed for a long time. XA transactions — the X/Open standard — allow distributed two-phase commit across multiple databases. Oracle has supported distributed transactions via database links for decades. PostgreSQL exposes PREPARE TRANSACTION for explicit two-phase commit. These are not theoretical capabilities; they are production-ready and well understood.

The microservices movement largely abandoned them. The engineering objections were legitimate: distributed transactions introduce latency, the transaction coordinator is a single point of failure, and blocking protocols create contention under load. Against those costs, eventual consistency with saga-based compensation seemed a reasonable exchange.

Those trade-offs were evaluated against a specific alternative: saga logic implemented and maintained by experienced service teams, operating against predictable failure modes. That is not the alternative we are evaluating now. The question is no longer whether distributed transactions are slower than eventual consistency in a well-designed microservices system. The question is whether eventual consistency managed by non-deterministic agents is an acceptable substitute for the transactional guarantees we set aside — and evaluated honestly against that comparison, the trade-off looks considerably less favourable.

It is worth noting that many modern cloud databases and SaaS platforms do not support XA at all — not because distributed transactions are technically infeasible, but because the architectural direction moved away from them and implementations followed. The capability gap is real even where the theoretical option exists.


The Multi-Database Reality

Even where distributed transaction support is available, it is rarely configured. An agent orchestrating across a typical modern data estate — a cloud relational database, a SaaS CRM, a document store, an analytics platform — is operating across systems where XA support is absent, partial, or simply not in place. Each system is ACID within its own boundary. Across the boundaries, there are no guarantees.

This was manageable when humans integrated across systems at human pace, with visibility into each step and the ability to detect inconsistencies before they propagated into decisions. At agent speed, across thousands of concurrent operations, inconsistency accumulates faster than any manual reconciliation process can address.

The architectural question this raises is unresolved, and we should say so plainly. Should agent adoption push organisations to configure distributed transaction support where it exists and choose platforms that support it where it does not? Should it constrain what agents are permitted to orchestrate across? Should it drive the development of compensation frameworks designed specifically for non-deterministic actors? None of these is straightforward. But the question needs to be asked directly, rather than left implicit in architectural choices made before agents were part of the picture.


Oracle’s Position

Oracle has argued for strong transactional guarantees throughout a decade in which that position was unfashionable. Its support for distributed transactions is genuine — database links with two-phase commit, XA compliance, and a long track record of enterprise deployments that depend on it. On the pure transactional argument, Oracle’s architecture was better positioned for this moment than the eventual consistency mainstream.

The more interesting question is whether an architecture that can enforce strong transactional guarantees — but whose surrounding ecosystem has moved to eventual consistency patterns — has the same properties in practice as one built around those guarantees from the outset. An agent orchestrating across Oracle and three SaaS platforms does not inherit Oracle’s transactional model for the cross-system operations. The strength of one component does not extend the transaction boundary. Oracle’s position is vindicated within its own scope; the boundary problem is shared with everyone else regardless.


What This Requires of Us

Strong transactions were not invented as a conservative reflex. They were the engineering response to a specific discovery: that data you cannot trust is more dangerous than no data, because it produces decisions that look correct.

The patterns we normalised over the past decade — sagas, eventual consistency, service-owned data — were rational responses to the engineering constraints of distributed systems and the organisational constraints of microservices. They were built for a world in which actors were deterministic, failure modes were bounded, and the teams operating the system had visibility into what was happening.

We are deploying agents into that world. The patterns need to be re-examined — not discarded, but re-examined honestly, against the actors we are actually introducing. The next question, which the following article takes up, is what happens when AI workloads require their own storage sitting outside the transactional boundary entirely: a problem that makes everything discussed here considerably harder.