[DB-SIG] Two-phase commit API proposal (was Re: Any standard for two phase commit APIs?)

James Henstridge james at jamesh.id.au
Fri Jan 25 01:54:40 CET 2008


On 24/01/2008, M.-A. Lemburg <mal at egenix.com> wrote:
> On 2008-01-24 15:36, M.-A. Lemburg wrote:
> > On 2008-01-24 02:44, James Henstridge wrote:
> >> I've had a bit more time to think about this, and have two proposals
> >> on how to handle transaction IDs.  I think they offer equivalent
> >> functionality, so the choice comes down to what we want the API to
> >> look like.
> >>
> >> Proposal 1:
> >> * Plain string IDs should work fine as transaction identifiers for
> >>   applications built from scratch with that assumption: they would
> >>   need to identify the global and branch parts in their own way.
> >>
> >> * A plain string can be stuffed inside an XA style transaction
> >>   identifier, even if it isn't making use of all the different
> >>   components.
> >>
> >> * Therefore, all methods accepting transaction IDs should accept
> >>   strings.
> >>
> >> * As some transaction IDs in the database might not match this simple
> >>   form, there are two options for the recover() method:
> >>     1. return a special object that represents the transaction, which
> >>        will be accepted by commit()/rollback().  How string-like must
> >>        these objects be?
> >>     2. omit such transaction IDs from the result.
> >>
> >> * For databases that support more structured transaction IDs (such as
> >>   those used by XA), the 2PC methods may accept objects other than
> >>   strings.
> >>
> >>
> >> Proposal 2:
> >>
> >> * Many databases follow the XA specification, so it makes sense to use
> >>   transaction identifiers structured in the same way.
> >>
> >> * For databases that do not use XA-style transaction IDs, it is
> >>   usually possible to serialise such an ID into a form that it can
> >>   work with.
> >>
> >> * Therefore, all methods accepting transaction IDs should accept
> >>   3-sequences of the form (formatID, gtrid, bqual).
> >>
> >> * For databases using non-XA transaction IDs, it is possible that some
> >>   transaction IDs might exist that do not match the serialised form.
> >>   The recover() method has two options:
> >>     1. return a special object representing the ID that will be
> >>        accepted by commit()/rollback().  Such an object should act
> >>        like a 3-sequence.
> >>     2. omit such transaction IDs from the result.
> >>
> >> * For databases not using XA-style transactions, the 2PC methods may
> >>   accept objects other than 3-sequences as transaction IDs.
> >>
> >>
> >> Both of these proposals seem to get rid of the main points of contention:
> >> * removes the xid() constructor from the spec.
> >> * allow use of simple objects (strings or tuples) as transaction IDs
> >> * provides an obvious way to expose database-specific transaction IDs.
> >
> > I'm coming to agree with Stuart that the conn.xid() might actually
> > help us with this.
> >
> > So I'd be in favor of proposal 2 and an .xid() constructor that
> > returns an object which provides a 3-sequence interface, e.g.

So is the 3-sequence behaviour intended to allow application code to
inspect a transaction ID, or are tpc_begin(), etc expected to accept
arbitrary 3-sequences too?

> >
> > # Wrap the IDs for use by the database module
> > xid = conn.xid(fid, gid, bid)
> >
> > # Use the xid
> > conn.tpc_begin(xid)
> > conn.tpc_prepare(xid)
> > ...
> >
> > # Unwrap the IDs:
> > fid, gid, bid = xid
>
> Plus require that all three components are strings to avoid the
> None issue.

If we are going with 3-part XA-style transaction IDs, the format ID
should be a non-negative 32-bit integer and the other two should be
strings with a maximum length of 64 bytes (possibly with some
restrictions on allowed characters?).

James.


More information about the DB-SIG mailing list