Transactions across multiple datasources — JtaTransaction… — Cracked Java
// Spring Framework & Spring Boot · Transactions Deep Dive
SeniorSystem DesignBig Tech

Transactions across multiple datasources — JtaTransactionManager, ChainedTransactionManager, or Saga.

A single @Transactional controls exactly one resource — the connection bound to one PlatformTransactionManager. The moment a business operation must commit across two datasources (or a DB and a message broker) atomically, you've left the comfort zone, and there's no free lunch: you choose between true distributed transactions, a best-effort coordination, or giving up atomicity for eventual consistency.

Option 1: JTA / XA — real distributed transactions

JtaTransactionManager backed by a JTA provider (Atomikos, Narayana) coordinates multiple XA-capable resources with two-phase commit (2PC): a prepare phase asks every resource "can you commit?", then a commit phase tells them all to commit. It gives genuine atomicity across datasources.

@Transactional   // backed by JtaTransactionManager, spans both XA datasources
public void transfer(Order o) {
    ordersRepo.save(o);        // XA datasource A
    ledgerRepo.record(o);      // XA datasource B  -> both commit or both roll back
}

The cost is real: every resource must support XA, 2PC adds latency and locking, and the transaction coordinator becomes a stateful component you must run and recover. Heavy, but the only path to true cross-resource atomicity.

Option 2: ChainedTransactionManager — best-effort

ChainedTransactionManager (Spring Data) simply chains several transaction managers: it begins all of them, runs your code, then commits them in reverse order. It is not 2PC — if the second commit fails after the first already committed, you're left inconsistent. It's "best-effort 1PC," cheap but unsafe at the boundary, and it's deprecated. Mention it only to say you know what it is and why you'd avoid it.

Option 3: Saga — embrace eventual consistency

For microservices, distributed transactions are usually the wrong shape. A Saga replaces one atomic transaction with a sequence of local transactions, each with a compensating action to undo it. If step 3 fails, you run compensations for steps 2 and 1. Orchestrated (a coordinator drives the steps) or choreographed (services react to each other's events). You trade atomicity for availability and accept temporary inconsistency.

Mark your status