[Jim Fulton]
>  From reading the source. they don't seem to fit the use case very well:
> - They are registered with the TM and are called for subsequent
>    transactions until they are unregistered.  This is not what we want
>    here.  We want hooks to be called only if the current transaction
>    commits.  We want to throw the hooks away at the end of the
>    transaction.
>    It's not obvious how to make this work with synchronizers.  (I suppose
>    the syncronizer could save the transaction it cares about
>    and unregister itself if it sees another.  This is a lot of bother.)

It's curious to consider the ways in which this fails to work:

import transaction

class OneShot:
    def __init__(self, hook, *args, **kws):
        self.hook = hook
        self.args = args
        self.kws = kws
        self.txnmgr = transaction.manager

    def beforeCompletion(self, txn):
        self.hook(*self.args, **self.kws)

    def afterCompletion(self, txn):

    def _remove(self):
        except KeyError:

That is, OneShot(hook, ...) tries to work exactly the same way as your
beforeCommitHook(hook, ...).

The most obvious failure is that the hook gets called on both commit() and
abort().  I view that as a mistake in the design of beforeCompletion; there
are currently no uses of beforeCompletion() anywhere in ZODB, so I doubt it
would cause any pain to change that.  Perhaps the hook method could be
passed a string arg, 'commit' or 'abort'.

A subtler failure is that "are called for subsequent transactions until they
are unregistered" isn't the full truth:  the TM holds only a weak reference
to a registered synchronizer.  If such a synchronizer becomes otherwise
unreferenced, it will vanish from the TM's weak set of registered
synchronizers, and then its methods won't get invoked at all.  If the caller
arranges to hold a strong reference to a OneShot instance until the current
transaction ends, then that part isn't an issue.

For more information about ZODB, see the ZODB Wiki:

ZODB-Dev mailing list  -  ZODB-Dev@zope.org

Reply via email to