I set the TransactionAttribute annotation to MANDATORY at the class level. I understand this means that all methods like doSomething () should be called in the incoming transaction. In this case, we use container-managed transactions.
Using class-level MANDATORY means that the container must throw an exception for the caller if the transaction is not executed when the FirstEjbType method is FirstEjbType .
Out of curiosity, who initiates the transaction? Is there a special reason not to use REQUIRED by default?
TransactionAttribute is not used at all in SecondEjbType or ThirdEjbType ... either at the class level or at the method level. I understand that this means that secondEjb.doSomething () and thirdEjb.doSomething () will work in the transaction provided for firstEjb.doSomething ()
This means that the default transaction attribute is used, i.e. REQUIRED , and the REQUIRED method REQUIRED guaranteed to be executed in a transaction (the container will start alone if ).
So, in your case, secondEjb.doSomething() and thirdEjb.doSomething() should be executed in transaction firstEjb.doSomething() .
Am I missing something obvious, or is my conceptual understanding basically correct, and could the problem be elsewhere?
The rule of thumb for propagating a persistence context in a transaction is that the persistence context is propagated when a JTA transaction is propagated. But there are some limitations. The JPA specification does the following:
5.6.3 Saving Context Reproduction
As described in section 5.1, one or more persistence contexts can correspond to one or more managers of JTA object instances (all associated with the same factory object manager).
The persistence context is saved through instances of the object manager as the JTA transaction is propagated.
Persistence persistence contexts apply only in the local environment. Save contexts do not apply to remote levels.
And Sahoo (from the GlassFish team) writes in more detail about propagation rules in disseminating resilience context :
3. (rule No. 3). Do not expect the PC to spread when the remote EJB is called, even if the remote EJB is running in the same JVM or part of the same application.
So, if you use JPA everywhere, I would expect that business methods called within the same transaction will inherit the same persistence context only if you don't use Remote interfaces (I don't know if this is a specific interpretation of the GlassFish specification but Sahoo speaks quite clearly about this limitation).
PS: JPA assumes the isolation level READ_COMMITTED (so that optimization locks can work), and the standard JPA does not allow you to configure isolation levels (well, some providers allow you to change it either worldwide or by request, but not portable).
PPS: I'm not sure isolation levels are the key to your problem.
References
- JPA 1.0 Specification
- Section 5.6.3 “Dissemination of the sustainability context”