Type: Feature Request
Status: Closed (View Workflow)
Resolution: Out of Date
Affects Version/s: 2.0 .Final
Fix Version/s: None
I have noticed some unexpected behaviour with the current workings of transactional observers. I have initially reported these issues under WELD-2444 , where Martin Kouba 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.