[
https://issues.apache.org/jira/browse/TOMEE-4727?focusedWorklogId=1046084&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1046084
]
ASF GitHub Bot logged work on TOMEE-4727:
-----------------------------------------
Author: ASF GitHub Bot
Created on: 07/Oct/26 06:29
Start Date: 07/Oct/26 06:29
Worklog Time Spent: 10m
Work Description: jungm opened a new pull request, #3063:
URL: https://github.com/apache/tomee/pull/3063
[TOMEE-4727](https://issues.apache.org/jira/browse/TOMEE-4727): a Jakarta
Data repository called from a CDI `@Observes(during = AFTER_SUCCESS)` observer
fails with `DataException: Transaction ... is not active`.
## Summary
After success observers run in `afterCompletion`, where the committed
transaction is still bound to the thread with status `STATUS_COMMITTED`.
`RepositoryInvocationHandler.executeInTransaction` joined it because it only
checked for `STATUS_NO_TRANSACTION`. [Jakarta Data 1.0
ยง7.3](https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0#_jakarta_transactions)
only requires joining an *active* transaction.
```diff
executeInTransaction
- if status == NO_TRANSACTION
- begin
- else
- join bound transaction
+ if status is ACTIVE or MARKED_ROLLBACK
+ join bound transaction
+ else
+ if a transaction is bound (completing / completed)
+ suspend it
+ begin
run operation
commit what we began
+ resume the suspended transaction
```
## Evidence
`JakartaDataTransactionalTest.findInsideAfterSuccessObserver`:
```text
@Transactional insertAndNotify("tx-observed") // fires ItemInserted
AFTER_SUCCESS observer -> repository.findById(id)
assert observer saw no exception and label == "tx-observed"
```
- **Before:** `AssertionError: Repository call in the observer failed:
jakarta.data.exceptions.DataException: Transaction
org.apache.geronimo.transaction.manager.TransactionImpl@4b3b2a4f is not active`
**After:** `arquillian-tomee-data-tests`: `Tests run: 9, Failures: 0,
Errors: 0, Skipped: 0`; `openejb-jakarta-data`: `Tests run: 183, Failures: 0,
Errors: 0, Skipped: 0`
## Merge Danger
**Door:** two-way
A single method in `openejb-jakarta-data`; reverting restores the old
behaviour.
**Blast Radius:** narrow
Only repository calls made while the bound transaction is neither active nor
marked for rollback change behaviour; those failed before. Calls inside an
active transaction and calls without one take the same path as before.
Issue Time Tracking
-------------------
Worklog Id: (was: 1046084)
Remaining Estimate: 0h
Time Spent: 10m
> 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
> Time Spent: 10m
> Remaining Estimate: 0h
>
> {{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)