users@jta-spec.java.net

[jta-spec users] Re: Automatic resource enlisting in Java EE - CDI Producers and EntityManager

From: Jens Schumann <jens.schumann_at_openknowledge.de>
Date: Thu, 14 Aug 2014 17:55:37 +0000

(Christian asked me the send my reply to his e-mail to the list directly. He changed his e-mail address, therefore his answer was rejected. Right now he is waiting for activation. See his answer below first)

------

Hi Christian,

Thanks for the reply. I have the feeling that your answer reflects more or less the "traditional" EJB style EntityManager behaviour and EJB-style transaction management. However with @Transactional and CDI producers the EE platform provides a way more fine-grained lifecycle and transaction control.

I am talking about the following scenario (disposer method omitted):

@ApplicationScoped
public class SomePersistenceUnit {
  @PersistenceUnit
  private EntityManagerFactory emf;

  @Produces @RequestScoped
  public EntityManager createEntityManager() {
    return emf.createEntityManager();
  }
}

From now on I can inject my own @RequestScoped EntityManager everywhere, participate in transactions if needed while ensuring that an EM is not closed after TX.commit(). Extended EnityManager without (stateful) EJB.

Even though it might be a rare scenario in the EE world as of today I can tell you that it will not be the case for ever. Most of the CDI folks I know recommend Producer Methods instead of using the old EJB style PersistenceContext. In the past they created their own TX support (which ended up as a deltaspike extension) and now they start using EE7 @Transactional. Quite often TX boundaries are moved up within applications, for instance simple CDI beans manage transactions if the related use case requires a transaction. No more required by default. Instead required based on use case decisions (and maybe mandatory at service//integration level).

Back to my original question:
Am I wrong that a regular XA resource joins an active JTA transaction during XA resource method invocations? E.g. a database Connection.executeStatement() will enlist the resource automatically? Or is this completely unspecified and just works since DB connections are usually pooled and need to handle enlistment differently?

Jens
PS: My colleagues and I have recommended this approach to a couple thousand people already. Just join us at JAX/WJAX in Germany;).


Von: Christian Von Kutzleben <Christian.VonKutzleben_at_actian.com<mailto:Christian.VonKutzleben_at_actian.com>>
Datum: Thursday 14 August 2014 08:52
An: "users_at_jta-spec.java.net<mailto:users_at_jta-spec.java.net>" <users_at_jta-spec.java.net<mailto:users_at_jta-spec.java.net>>
Cc: Jens Schumann <jens.schumann_at_openknowledge.de<mailto:jens.schumann_at_openknowledge.de>>
Betreff: AW: Automatic resource enlisting in Java EE - CDI Producers and EntityManager


Hi Jens,


AFAIK this is not a specified behavior and your assumption is wrong.


However, IMO the set of scenarios, where this matters is really limited:


During a bean invocation, there is a distributed transaction or there is none. This can

only change in between bean invocation.


So it matters only for a transactional resource which has a lifespan across multiple bean

invocations, e.g. an EntityManager kept in a stateful session bean.


Let's assume, there are 2 bean invocations, and in between a transaction is started:


The transaction type of the bean can be:


Mandatory: first invocation fails

Required: first invocation is a separate (container started and committed) transaction

Requires_New: both invocation are separate, container started and committed transactions

Never: second invocation fails

Not_Supported: transaction is suspended before second invocation


last, but not least:

Supports: this is the only mode, where this can happen:


the first invocation can run without a transaction (if a resource local transaction is started by the bean,

we would be again in a different scenario with two independent transactions)


With JPA you can do many things outside a transaction, however nothing can be flushed down to

the database.


For the second invocation it might be useful, to enlist the entity manager with the transaction (which

makes changes of the first invocation becoming part of this transaction).


For me, this is a very rare scenario, and I think it is perfectly fine here, to require an explicit "joinTransaction()" call

during the second invocation.


Christian