The value-free identity of an XA transaction (ADR-0006, Rule 1).
gtrid/bqual are application-chosen bytes — row-value class — so the pool keys on
a sha256 digest of the canonical XID frame, and the raw bytes are never stored,
logged, or emitted. Even the digest is never emitted (a digest of a low-entropy
application XID is dictionary-reversible); it exists as the in-memory pool key ONLY.
Telemetry and errors correlate on server-assigned GTIDs, never on anything
XID-derived.
Both XID encodings capstan sees produce the same digest:
- the
XA_prepare_log_event(type 38) body —one_phasebyte,format_id/gtrid_length/bqual_lengthas little-endian u32s, then the raw bytes (layout read from the MySQL server source,control_events.cpp); - the resolution
QUERYtext —XA COMMIT X'<hex gtrid>',X'<hex bqual>',<format_id>(andXA ROLLBACK), the canonical hex-literal form the server writes (captured live;test/fixtures/binlog/xa/).
Summary
Types
A parsed resolution statement: the verb and its XID digest.
A parsed XID's value-free identity: the sha256 digest of the canonical frame.
Functions
The digest of a canonical XID. The frame is namespaced and length-prefixed so no
two distinct {format_id, gtrid, bqual} triples collide.
Parses an XA COMMIT/XA ROLLBACK resolution QUERY text into its verb + digest.
Types
@type resolution() :: {:commit | :rollback, t()}
A parsed resolution statement: the verb and its XID digest.
@type t() :: <<_::256>>
A parsed XID's value-free identity: the sha256 digest of the canonical frame.
@type xid() :: %{ one_phase: boolean(), format_id: non_neg_integer(), gtrid: binary(), bqual: binary() }
Functions
The digest of a canonical XID. The frame is namespaced and length-prefixed so no
two distinct {format_id, gtrid, bqual} triples collide.
@spec parse_resolution(String.t()) :: {:ok, resolution()} | :error
Parses an XA COMMIT/XA ROLLBACK resolution QUERY text into its verb + digest.
Accepts exactly the canonical hex-literal form the server writes
(XA COMMIT X'…',X'…',<format_id>); a bare XA COMMIT-shaped text with no XID
(or any other shape) returns :error — the caller treats an unparseable
resolution as unmatched and fails closed, never guesses.