Matej Novotny commented on CDI-724:
bq. In my opinion would be best to just throw an exception if the synchronisation cannot
I cannot really see where would this exception be thrown and where would the user monitor
As for interposed synchronization - there is no way to know when CDI should register an
interposed sync. and when it should register the ordinary one. Besides registering
interposed carries additional risks; user logic may depend on certain resources which may
or may now be available once you start executing interposed sync. callbacks.
bq. It also should be pretty easy to work around by just placing a single synchronisation,
and queueing transactional observers in a transaction scoped queue.
This looks like a good way to approach it. If we do that, we need to remember to correct
spec at [10.5. Observer
we currently forbid it by saying:
??for each observer method, either invoke the observer method immediately, or register the
observer method for later invocation during the transaction completion phase, using a JTA
Transactional observers fired in inconsistent manner when
synchronisation cannot be placed
Project: CDI Specification Issues
Issue Type: Feature Request
Affects Versions: 2.0 .Final
Reporter: Jan-Willem Gmelig Meyling
I have noticed some unexpected behaviour with the current workings of transactional
observers. I have initially reported these issues under WELD-2444 , where [~mkouba]
pointed out that WELD simply followed the CDI spec here:
??If the transaction is in progress, but javax.transaction.Synchronization callback
cannot be registered due to the transaction being already marked for rollback or in state
where javax.transaction.Synchronization callbacks cannot be registered, the before
completion, after completion and after failure observer methods are notified at the same
time as other observers, but after_success observer methods get skipped.??
This choice has to some very unexpected side effects, namely:
* If the synchronisation cannot be placed, AFTER_FAILURE observers will be invoked, even
if the actual transaction already succeeded or is about to succeed. This may confuse users
that expect the AFTER_FAILIURE observer to be invoked if and only if the actual
transaction rolled back.
* If the synchronisation cannot be placed, AFTER_FAILURE and AFTER_COMPLETION will be
invoked immediately. This may confuse users that expect the actual transaction to be
completed during the execution of the AFTER_FAILURE and AFTER_COMPLETION observers. Now,
these observers may be invoked while still committing or rolling back.
* If the synchronisation cannot be placed, the exception is swallowed silently (with the
only mechanism to observe the failure being the unfortunate invocation of the
AFTER_FAILURE observer). This may make it very difficult for someone trying to figure out
why the AFTER_SUCCESS transactional observer was never invoked in the first place, even
though the transaction did commit.
In my opinion would be best to just throw an exception if the synchronisation cannot be
placed, all of the above quirks will then be resolved. It also should be pretty easy to
work around by just placing a single synchronisation, and queueing transactional
observers in a transaction scoped queue.
While at it: the issue originates from the fact that the synchronisation couldn't be
added during the COMMITTING state. While I do understand this limitation, I think it might
be worthwhile to consider to use an interposed (run last) synchronisation rather than
plain transaction synchronisations. This would AFAIK also allow placing additional
synchronisations while processing the existing synchronisations (except the interposed
synchronisations that is). This can for example come in handy, when fireing events from
JPA entity lifecycle listeners (which are typically invoked during FLUSH, which itself is
triggered through a transaction synchronisation).
This message was sent by Atlassian Jira