Alexander Falb commented on DELTASPIKE-900:

To summarize the problem: When using a Bean with more than one EntityManger, a 
Transactional method and {{BeanManagedUserTransactionStrategy}} the transaction 
is not committet.

I had a chat with [~jtestori] and did a bit of debugging and found out that
                if (!transaction.isActive())
                    beforeBegin(invocationContext, entityManagerEntry, 
                else if (isOutermostInterceptor)
                    outermostTransactionAlreadyExisted = true;
starts a transaction for the first EntityManager. Afterwards the 
{{BeanManagedUserTransaction#beforeProceed}} joins this Transaction. Now the 
code above runs again for the 2nd EntityManager. But because the transactions 
are joined, the new transaction is already active (else path) and because this 
interceptor is the outermost {{outermostTransactionAlreadyExisted = true;}} is 
 Because of this, neither the exception handling (catch) does a transaction 
rollback nor the finally a transaction commit.

Based on [~jtestori]'s idea of tracking if the current interceptor opened the 
transaction or not I created a fix for this issue: 

Deltaspike still builds without test failures, however I'm not sure any tests 
actually touch {{BeanManagedUserTransactionStrategy}}.

> ResourceLocalTransactionStrategy not working with multiple EntityManagers
> -------------------------------------------------------------------------
>                 Key: DELTASPIKE-900
>                 URL: https://issues.apache.org/jira/browse/DELTASPIKE-900
>             Project: DeltaSpike
>          Issue Type: Bug
>          Components: JPA-Module
>    Affects Versions: 1.2.1, 1.3.0
>            Reporter: Johannes Testori
>            Assignee: Mark Struberg
>            Priority: Major
> We are using CDI-ApplicationScoped services in a batch program with 
> CdiControl. We started using multiple qualified EntityManagers in a single 
> service annotated with @Transactional and encountered the problem that 
> database changes are not committed. After some debugging we found the problem 
> in the "execute"-method in ResourceLocalTransactionStrategy.
> for (Class<? extends Annotation> emQualifier : emQualifiers)
> {
>     EntityManager entityManager = 
> resolveEntityManagerForQualifier(emQualifier);
>     EntityManagerEntry entityManagerEntry = 
> createEntityManagerEntry(entityManager, emQualifier);
>     transactionBeanStorage.storeUsedEntityManager(entityManagerEntry);
>     EntityTransaction transaction = getTransaction(entityManagerEntry);
>     if (!transaction.isActive())
>     {
>         beforeBegin(invocationContext, entityManagerEntry, transaction);
>         transaction.begin();
>     }
>     else if (isOutermostInterceptor)
>     {
>         outermostTransactionAlreadyExisted = true;
>     }
>     //don't move it before EntityTransaction#begin() and invoke it in any case
>     beforeProceed(invocationContext, entityManagerEntry, transaction);
> }
> A transaction is created for the first EntityManager. But since the same 
> transaction is assigned to the other EntityManagers, 
> "outermostTransactionAlreadyExisted" is set to true. This is the cause for 
> the transaction not being committed afterwards:
> if (isOutermostInterceptor)
> {
>     if (!outermostTransactionAlreadyExisted)
>     {
>         // We only commit transactions we opened ourselfs.
>         // If the transaction got opened outside of our interceptor chain
>         // we must not handle it.
>         // This e.g. happens if a Stateless EJB invokes a Transactional CDI 
> bean
>         // which uses the BeanManagedUserTransactionStrategy.
> We've seen this problem in version 1.2.1 and 1.3.0. (didn't try other 
> versions).

This message was sent by Atlassian JIRA

Reply via email to