>>> ... it should be better to add addAfterCommitHook to
>>> transaction as in addBeforeCommitHook.
> yup it could be really useful to trigger non transactionnal code from
> there. We might use this in here with our CPSRelation product and the rdf
> db we are using. I could find a project to test this in real life :)
It intensifies an issue only hinted at before: non-transactional code in an
after-commit hook is clearly no problem, but what about transactional code?
"The next" Transaction object (for the transaction that will follow the
current one in time) doesn't exist yet, and any interaction with the current
Transaction object will be lost. Trying to call addBeforeCommitHook()
during an after-commit hook was mentioned before, but it's not the only
fuzzy case. What if, e.g., an after-commit hook modifies a persistent
object? Tries to do a commit() of its own?
before-commit hooks are less puzzling this way, because they clearly occur
while the current transaction is still in mid-stream.
> I can take care of this if nobody else is interested to do it. I can
> surely do this by the end of the week.
Cool again. And that's a lot faster than I could make time to review it
>> Fuzzy: what happens if an after-commit hook invokes
>> addBeforeCommitHook()? I think it should be a (detected) error. (The
>> current transaction is winding down, and it's "too early" to try adding
>> hooks to the next transaction -- it doesn't exist yet.)
> When you mean "detected error" you mean an exception is raised or just
> the error is caught and ignored within the internals ?
I mean that the interface defines it as an error, and that it's guaranteed
an exception will be raised if it occurs. Alas, if we view the after-commit
hook as being called "in" the current transaction, there are mounds of
things that should be considered errors (any transactional code). OTOH, if
we view the after-commit hook as running at the very start of "the next"
transaction, the implementation becomes harder to picture (although the edge
case semantics become clearer: the after-commit hooks run "in" a
well-defined transaction then).
>> Fuzzy: should after-commit hooks be called before or after the
>> afterCompletion() methods of registered synchronizers? The analogous
>> question wrt before-commit hooks and beforeCompletion() methods was left
>> unanswered, and I'm happy enough leaving it undefined here too.
> Let's discuss and fix this in a second step for both before and after
> commit hook system ?
Leaving something undefined doesn't necessarily mean it's broken. It means
instead that the implementation is free to do whatever it wishes, and code
relying on undefined behavior is itself in error (although perhaps not a
"detected error"). For example, it so happens that beforeCompletion()
methods are called after before-commit hooks today. Because the interface
doesn't define the relative ordering of these things, that's fine. The
implementation tomorrow could do them in the other order. If there isn't a
_reason_ ("use case") to specify the order, it's good to leave it undefined
(gives the implementation more freedom, spares writing mounds of tedious
test code verifying artificial constraints nobody cares about, and spares
burdening readers with mounds of tedious interface docs defining artificial
constraints nobody cares about ;-)).
For more information about ZODB, see the ZODB Wiki:
ZODB-Dev mailing list - ZODB-Dev@zope.org