[Zope-dev] External transaction integration bug?

Randall F. Kern randy@spoke.net
Wed, 18 Apr 2001 19:53:22 -0700


I may just be missing something obvious here, but it seems like there is
a hole in ZODB.Transaction.Transaction.commit and Shared.DC.ZRDB.TM.TM,
that can cause external transactions (those that use the TM mixin class,
like psycopg) to be abandoned (never get committed or rolled back).

Let's say somewhere around line 300 in Transaction.py (the call to
j.commit(o, self)) we get an exception.  Furthermore, let's say the TM
derived database object has already been committed (the only effect of
which is to move the DB into the jars mapping, since TM.tpc_begin() and
TM.commit() both do nothing).

The exception dumps us down to about line 353, where we call
_p_jar.abort() on all the uncommitted objects (note: it's important that
the database connection isn't in this list, because TM.abort() will
rollback the transaction.  the way we keep the db out of this list is by
having it appear in objects _before_ the object that failed the commit).

Next we reach line ~366, where we should "unwind TPC for the jars that
began it".  What this means is calling tpc_abort() on each jar from the
objects that were already committed (which includes the database).
However, TM.tpc_abort() does nothing, leaving the external database
transaction open.

Does this make sense?

If this makes sense (i.e. seems bad :), does catching tpc_abort() in TM
and calling TM.abort() seem like a valid fix?

Thanks,
-Randy