[DB-SIG] Two-phase commit API proposal (was Re: Any standard for two phase commit APIs?)
James Henstridge
james at jamesh.id.au
Mon Jan 21 12:09:12 CET 2008
On 21/01/2008, Federico Di Gregorio <fog at initd.org> wrote:
> I agree with your analisys, I'll add some comments about the proposal
> below.
>
> Il giorno lun, 21/01/2008 alle 19.08 +0900, James Henstridge ha scritto:
> > 1. Add a Connection.begin(...) method that explicitly starts a
> > transaction. Some argument (possibly the transaction ID) causes
> > the transaction to use two-phase commit. May raise
> > NotSupportedError if two-phase commit is not supported.
>
> DBAPI always had implicit transaction begin (for backends supporting
> transactions) and adding an explicit begin() method would just add
> confusion onto the user. "Should I always call begin()? Or just when I
> want to start a two-phase?". I'd better like the two-phase begin method
> named otherwise. Let's call it xa_begin() in this discussion.
I don't have a strong opinion here. I used begin() in the proposal
because the method is currently available in many adapters to
explicitly start a transaction (even though they'll implicitly start a
transaction otherwise).
Extending the method seemed easier, and is what cx_Oracle did.
> > 2. Add a Connection.prepare() method that peforms the first stage of
> > two-phase commit. May raise NotSupportedError if two-phase commit
> > is not supported, or the transaction was not started in two-phase
> > mode.
> >
> Ok. (Should be named accordingly with the begin method.)
I used prepare() in the proposal because that's what cx_Oracle and
kinterbasdb are already doing.
> > 3. Calling commit() or rollback() on the connection after prepare()
> > performs the second stage of the commit.
> >
> Ok.
>
> > 4. Calling commit() or rollback() on the connection prior to
> > prepare() performs a one-phase commit or rollback.
> >
> IMHO, it should raise an error if the transaction was started for
> two-phase. Otherwise I don't see any reason for (1).
I disagree here. If a problem is detected early in the transaction,
calling prepare() before rollback() on the other members of the global
transaction is a waste of effort.
As for commit(), the transaction manager can use one-phase commit for
the last resource without integrity problems. I don't see much value
in preventing this optimisation.
> > 5. Executing statements after prepare() but before commit() or
> > rollback() results in an error (ProgrammingError?)
> >
> Ok.
>
> > 6. Closing a connection with a prepared but uncommitted transaction
> > rolls back that transaction.
> >
> Stuart's comment on psycopg ML made me think about this one. Maybe we
> want an option added to xa_begin() to keep the prepared transaction open
> even if the connection drops.
Perhaps. I haven't really thought much about the recovery side of the API.
James.
More information about the DB-SIG
mailing list