Towards Abstractions for
Composable Transactional Isolation


Daniel Pereira · Filipe Pereira · Rui Lopes · Nuno Faria · Paulo Sérgio Almeida · José Pereira

INESC TEC and University of Minho · InvisibleLab

Motivation

The need for composable transactional isolation


  • Query processing, execution, storage and formats are reusable parts now. A specialised engine can be assembled out of them without losing performance or functionality.
  • Isolation, concurrency control, transaction metadata and replication stayed inside the engine. XA is the one standard that aimed at transactions, and it stopped at atomicity and durability.
  • Case study: Transactional Causal Consistency (TCC) is the strongest consistency compatible with availability under partition.
  • Adopting it has meant building a complete stack: AntidoteDB uses the Cure protocol that describes fine-grained operations on versions and timestamps.
The question

Can TCC be composed from what relational databases already do rather than built from scratch?

Background

TCC in a nutshell


Space-time diagrams throughout: time runs to the right, an open circle starts a transaction and a filled dot commits it, a dashed vertical is a reader's snapshot, and a hatched band is written to storage but not yet visible.

A transaction's snapshot must be closed under causal dependencies: if it has an effect, it has everything that precedes it.

A multi-object transaction is visible all at once or not at all — stronger than failure atomicity, which ignores concurrent readers.

What TCC allows. No global commit order, and no aborts on write conflict — so long fork and lost update are permitted, as is write skew (short fork), which SI already allows. Cure recovers lost updates with CRDTs; they are not intrinsic to TCC.

Background

What we are composing from


Visibility guarantees

  • RC — snapshot refreshed per statement. Non-repeatable and phantom reads.
  • SI — one stable snapshot per transaction. Still allows write skew.
  • DSI — SI whose snapshot is consistent across nodes, so no fractured versions.

Who provides what

  • PostgreSQL — MVCC, SI; xid / xmin / xip_list, LSN, optional track_commit_timestamp.
  • Citus — shards + 2PC, but each node keeps its own snapshot. No DSI.
  • CockroachDB · YugabyteDB — DSI or stronger, from a single scalar commit timestamp.
  • TiQuE — isolation expressed in SQL: versions and metadata in ordinary tables, queries rewritten with WHERE.

Experiment

One architecture, three scenarios


The agent's job

  • Capture committed updates (CDC).
  • Exchange them in batches, each carrying a dependency.
  • Apply remote batches with ordinary SQL.
  • Keep current version in its own tables.

The visibility layer appears only in the scenarios that need it. Either way the application sees an ordinary database.

Scenario 1 · one node, one agent per DC

First problem: atomic visibility of updates


Takeaway 1

Applying each batch as a transaction provides atomic visibility, while agent-enforced order keeps the installed state causally closed. PostgreSQL's native SI can therefore expose causally consistent snapshots to clients.

Scenario 2 · many nodes, one agent per DC

Atomic commitment is not atomic visibility


-- rewritten, TiQuE-style
WHERE t.k <= AppliedVV[t.d]

Visibility moves into the query and the database is left needing only row-level atomicity. A near miss: PostgreSQL already has SET TRANSACTION SNAPSHOT — in Citus it applies to the coordinator's local transaction only.

Takeaway 2

DSI makes it straightforward to use many nodes per DC with a single agent. But it would not be necessary if a coordinator could explicitly set each node's snapshot when starting a distributed transaction.

Scenario 3 · many nodes, one agent each

Where DSI no longer suffices


Per-shard dependencies are all an agent can enforce, and agent coordination doesn't fix it. So visibility moves to the reader: a commit vector per item.

Takeaway 3

Remote transactions are materialised as independent physical transactions across nodes, so even native DSI cannot ensure their atomic visibility. Enforcing TCC requires a logical visibility layer.

Not covered today

The second problem: commit assignment


  • Once visibility is expressed through transaction metadata, something has to assign each transaction's commit position...
  • No time! See §4.2 of the paper.

Summary

What each deployment costs


Scenario Nodes
per DC
Agents
per DC
Isolation
required
Replication
ordering
Visibility
layer
Transaction
timestamp
Agent
timestamp
S111SIcausal nononevector
S2 · CDB, YDBN1DSIcausal nononevector
S2 · CitusN1rowcausal yesscalarvector
S3NNrowFIFO yesvectorvector

Shaded rows are where we re-implement, in SQL, the version management the database already has.

Conclusions

Two interfaces would cover most of this


  • Storage and query processing became composable; transactional isolation did not — adopting a model such as TCC has meant building a new database.
  • A thought experiment: TCC over PostgreSQL, Citus, CockroachDB and YugabyteDB, in three scenarios of growing distribution.

Neither is SQL the application writes: the agent supplies the snapshot and collects the commit position, on connections the application never sees.

Set the starting snapshot

-- per node, at transaction start
BEGIN WITH SNAPSHOT <external>

Lets an external component define the causally consistent cut instead of reconstructing it with WHERE clauses. Citus-style architectures would then need no DSI at all, and scenario 3 would need no visibility layer.

Get a durable commit position

-- at the effective commit point
COMMIT RETURNING <position>

The second gap, not covered today. The commit position exists only after the commit, so visibility expressed through it breaks read-your-writes unless the position is exposed atomically at the commit point.

The obstacle to composable isolation is not missing mechanisms — it's the absence of interfaces onto the ones already there.


Thank you


Daniel Pereira · Filipe Pereira · Rui Lopes · Nuno Faria · Paulo Sérgio Almeida · José Pereira

INESC TEC and University of Minho · InvisibleLab

Co-funded by the European Regional Development Fund through Portugal 2030 — COMPETE 2030, project CDMS (ref. 17409, COMPETE2030-FEDER-01193000); NORTE 2030, projects Rescueware (ref. 21746, NORTE2030-FEDER-02306900) and BCD.S+M (ref. 14436, NORTE2030-FEDER-00584600). Financed by national funds through FCT — Fundação para a Ciência e a Tecnologia: UID/50014/2025, and CMU–Portugal project ADAPQO (2024.12585.CMU).