[
https://issues.apache.org/jira/browse/TOMEE-4727?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Markus Jung updated TOMEE-4727:
-------------------------------
Description:
{{RepositoryInvocationHandler.executeInTransaction}} only starts its own
transaction when {{TransactionManager.getStatus()}} returns
{{STATUS_NO_TRANSACTION}}, and joins the thread's transaction in every other
state.
A CDI {{@Observes(during = TransactionPhase.AFTER_SUCCESS)}} observer runs in
the transaction's {{afterCompletion}} callback, where the committed transaction
is still bound to the thread with status {{STATUS_COMMITTED}}. A repository
call from such an observer joins the finished transaction and fails:
{code}jakarta.data.exceptions.DataException: Transaction
org.apache.geronimo.transaction.manager.TransactionImpl@3d803bed is not active
at
org.apache.webbeans.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:377)
at
org.apache.webbeans.ee.event.TransactionalEventNotifier$AfterCompletionSuccess.afterCompletion(TransactionalEventNotifier.java:208)
at
org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:335)
...
{code}
[Jakarta Data 1.0, section 7.3 "Jakarta
Transactions"|https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0#_jakarta_transactions]
requires a repository operation to join the global transaction only when
bq. a global transaction is active on the thread of execution in which a
repository operation is called
[CDI 4.1, section 9.5.3 "Observer method invocation
context"|https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1#observer_method_invocation_context]
allows such observers and leaves their transaction context open:
bq. if the observer method is any other kind of transactional observer method,
it is called in an unspecified transaction context, but with the same lifecycle
contexts as the transaction that just completed.
Fix: join only a {{STATUS_ACTIVE}} or {{STATUS_MARKED_ROLLBACK}} transaction;
in any other state suspend the bound transaction, run the operation in a new
one, and resume the bound transaction afterwards.
was:
{{RepositoryInvocationHandler.executeInTransaction}} only starts its own
transaction when {{TransactionManager.getStatus()}} returns
{{STATUS_NO_TRANSACTION}}, and joins the thread's transaction in every other
state.
A CDI {{@Observes(during = TransactionPhase.AFTER_SUCCESS)}} observer runs in
the transaction's {{afterCompletion}} callback, where the committed transaction
is still bound to the thread with status {{STATUS_COMMITTED}}. A repository
call from such an observer joins the finished transaction and fails:
{code}jakarta.data.exceptions.DataException: Transaction
org.apache.geronimo.transaction.manager.TransactionImpl@3d803bed is not active
at
org.apache.webbeans.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:377)
at
org.apache.webbeans.ee.event.TransactionalEventNotifier$AfterCompletionSuccess.afterCompletion(TransactionalEventNotifier.java:208)
at
org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:335)
...
{code}
Jakarta Data 1.0, section 7.3 "Jakarta Transactions"
(https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0#_jakarta\_transactions),
requires a repository operation to join the global transaction only when
bq. a global transaction is active on the thread of execution in which a
repository operation is called
CDI 4.1, section 9.5.3 "Observer method invocation context"
(https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1#observer\_method\_invocation\_context),
allows such observers and leaves their transaction context open:
bq. if the observer method is any other kind of transactional observer method,
it is called in an unspecified transaction context, but with the same lifecycle
contexts as the transaction that just completed.
Fix: join only a {{STATUS_ACTIVE}} or {{STATUS_MARKED_ROLLBACK}} transaction;
in any other state suspend the bound transaction, run the operation in a new
one, and resume the bound transaction afterwards.
> Jakarta Data repository fails when called from an AFTER_SUCCESS transactional
> observer
> --------------------------------------------------------------------------------------
>
> Key: TOMEE-4727
> URL: https://issues.apache.org/jira/browse/TOMEE-4727
> Project: TomEE
> Issue Type: Bug
> Reporter: Markus Jung
> Priority: Major
>
> {{RepositoryInvocationHandler.executeInTransaction}} only starts its own
> transaction when {{TransactionManager.getStatus()}} returns
> {{STATUS_NO_TRANSACTION}}, and joins the thread's transaction in every other
> state.
> A CDI {{@Observes(during = TransactionPhase.AFTER_SUCCESS)}} observer runs in
> the transaction's {{afterCompletion}} callback, where the committed
> transaction is still bound to the thread with status {{STATUS_COMMITTED}}. A
> repository call from such an observer joins the finished transaction and
> fails:
> {code}jakarta.data.exceptions.DataException: Transaction
> org.apache.geronimo.transaction.manager.TransactionImpl@3d803bed is not active
> at
> org.apache.webbeans.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:377)
> at
> org.apache.webbeans.ee.event.TransactionalEventNotifier$AfterCompletionSuccess.afterCompletion(TransactionalEventNotifier.java:208)
> at
> org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:335)
> ...
> {code}
> [Jakarta Data 1.0, section 7.3 "Jakarta
> Transactions"|https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0#_jakarta_transactions]
> requires a repository operation to join the global transaction only when
> bq. a global transaction is active on the thread of execution in which a
> repository operation is called
> [CDI 4.1, section 9.5.3 "Observer method invocation
> context"|https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1#observer_method_invocation_context]
> allows such observers and leaves their transaction context open:
> bq. if the observer method is any other kind of transactional observer
> method, it is called in an unspecified transaction context, but with the same
> lifecycle contexts as the transaction that just completed.
> Fix: join only a {{STATUS_ACTIVE}} or {{STATUS_MARKED_ROLLBACK}} transaction;
> in any other state suspend the bound transaction, run the operation in a new
> one, and resume the bound transaction afterwards.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)