问题
Are Java EE 6 CDI events transactional?
If I fire an event in a transaction, and subsequently roll back the transaction, are the effects of the Event listener rolled back as well?
Is this behaviour dependent on the event listener itself supporting transactions?
What about if I try and roll-back the exception from within then event listener, does it roll-back the transaction that fired the event?
回答1:
From the events chapter of the CDI 1.0 specification, one can define an event to be "transactional" by specifying the TransactionPhase one is observing, where TransactionPhase is one of:
- IN_PROGRESS,
- BEFORE_COMPLETION,
- AFTER_COMPLETION,
- AFTER_FAILURE,
- AFTER_SUCCESS
Such a declaration looks like:
void onDocumentUpdate(@Observes(during=AFTER_SUCCESS) @Updated Document doc) { ... }
If the observer is not declared to be "transactional", then the container calls the observer immediately, otherwise it registers the observer method for later invocation during the transaction completion phase, using a JTA Synchronization.
However:
Any observer method called before completion of a transaction may call setRollbackOnly() to force a transaction rollback. An observer method may not directly initiate, commit or rollback JTA transactions.
If the observer method throws an exception (and is itself not "transactional") the exception aborts processing of the event.
So, to achieve the behaviour I'm looking for, I believe I would register my observer as "transactional", and specify the BEFORE_COMPLETION TransactionPhase. I would then call setRollbackOnly() if I wanted to rollback the transaction that initiated the event.
来源:https://stackoverflow.com/questions/4228428/are-java-ee-6-cdi-events-transactional