XA transactions let IBM MQ participate in the same global commit decision as your database, message-driven partner, or second queue manager resource. Without XA, you might MQCMIT while Db2 rolls back—money moved in SQL but notification never sent, or message sent twice after ambiguous failure. With XA, a transaction manager runs two-phase commit: prepare asks every resource if it can commit; commit makes all permanent or rollback undoes all. Enterprise Java servers, Spring with XA DataSource, and z/OS RRS/CICS paths implement this for decades. Beginners should know when they are inside global transactions versus local MQ-only syncpoints, what indoubt means in overnight ops pages, and why mixing manual MQCMIT with container XA breaks atomicity. This tutorial explains roles (application, transaction manager, resource manager), two-phase flow, MQ as XA resource, failure and recovery, contrast with local UOW, and mainframe coordination with Db2.
Application performs business logic and enlists resources. Transaction manager (TM) owns the global transaction ID and drives prepare/commit. Resource managers (RM) include IBM MQ queue manager and Db2. MQ XA interface registers with TM; application rarely calls xa_* directly in modern stacks—containers do enlistment.
| Aspect | Local MQ UOW | XA global |
|---|---|---|
| Coordinator | MQ queue manager | Transaction manager |
| Participants | MQ only | MQ + Db2 + others |
| Commit API | MQCMIT | tm.commit() / container |
| Failure risk | MQ vs DB mismatch if both used | Atomic all-or-nothing |
| Indoubt | Rare on single QM | Recovery after TM crash |
1234567891011121314Simplified XA flow: App -> TM: begin() App -> MQ: put (enlisted) App -> DB: insert (enlisted) App -> TM: commit() TM -> MQ: prepare -> OK TM -> DB: prepare -> OK TM -> MQ: commit TM -> DB: commit If DB prepare fails: TM -> MQ: rollback TM -> DB: rollback
XA is two judges who must both say yes before the contest result counts. If one judge says no, the whole competition is cancelled for everyone—even if the other judge already liked your performance.
JMS XA connection factory and JTA UserTransaction enlist MQ. @Transactional on a service method using XA DataSource and JmsTemplate can commit both. Misconfiguration uses non-XA connection—silent split brain. Verify connection factory is XA-enabled in deployment descriptor or Spring config.
Resource Recovery Services coordinates Db2, MQ, and other RRS-capable resources on LPAR. CICS global transactions include MQ in the task syncpoint when defined. Batch with RRS uses standard mainframe recovery. Operators use ISPF recovery panels and IBM docs for indoubt resolution—not desktop MQCMIT alone.
TM crashes after prepare leaves MQ or Db2 indoubt—DISPLAY and recovery utilities show state. Heuristic rollback or commit is last resort with audit. Prevention: stable TM cluster, timeouts, idempotent consumers. Application logs global transaction id when exposed for correlation.
Two-phase commit costs more round trips than local MQCMIT. High-throughput fire-and-forget may skip XA intentionally accepting eventual consistency patterns (outbox table, saga). Choose XA when financial atomicity mandates it.
Saga pattern: local commit MQ, later compensate with reversal message. Outbox: write event row and MQ in one DB transaction without XA by reading outbox poller. Understand compensating actions versus true atomicity.
XA is when you and your friend both have to press okay on the tablet before the pizza order sends—if one presses cancel, the order is cancelled for both.
Draw prepare/commit sequence for MQ put + SQL insert.
When would you choose saga over XA for microservices?
Research how your app server configures XA JMS connection factory.
1. XA coordinates:
2. Two-phase commit phase 1 is:
3. Indoubt means:
4. Local MQCMIT without XA: