3
votes

We are using Spring with Hibernate to establish transactions with JTA. The PlatformTransactionManager is the JtaTransactionManager which is wired with the TransactionManager and UserTransaction from narayana.

@Bean
@Scope("prototype")
public TransactionManager jbossTransactionManager() {
    return jtaPropertyManager.getJTAEnvironmentBean().getTransactionManager();
}

@Bean
@Scope("prototype")
public UserTransaction jbossUserTransaction() {
    return jtaPropertyManager.getJTAEnvironmentBean().getUserTransaction();
}

@Bean
public PlatformTransactionManager transactionManager() {
    return new JtaTransactionManager(jbossUserTransaction(), jbossTransactionManager());
}

I have noted that JtaTransactionManager has the UT and TM I would want. On JBoss 6 EAP, I noted that my DataSource has been used as a WrapperDataSource and that this was related to a different TM. Specifically, it is using the TransactionManagerDelegate. This appears to be the transaction manager provided by JBoss via the JNDI names java:TransactionManager and java:jboss/TransactionManager. This is preventing my transactions from having transactional boundaries and I leak data on flush. If I remove my configuration and the UT and TM from the container, my transactions transact properly.

  1. What is deciding to use this other TransactionManager? This appears to be the JCA from the container but I do not understand the mechanism for this decision.
  2. Should I remove my UT and TM and surrender control to the container to give these components to my app and rely on the JTA platform as is or should I try to gain more control?
1
This is preventing my transactions from having transactional boundaries and I leak data on flush. please explain this with more details. It's difficult to understand what it means.ben75
I can see that Hibernate believes it is in a transaction. As a result, it performs the auto flush which expects the physical transaction to keep the data out of the database. Specifically, I can debug into ActionQueue#executeActions in Hibernate and see that the data is not committed before the executeActions( insertions ); and that it is in the database afterwards. (Verified by a different program manually querying the database. I am starting to believe that JBoss's JCA is deciding to use this other TransactionManager rather than my Spring bean version. I do not yet fully grok this.user2832162

1 Answers

0
votes

the container provides the datasource with a transaction manager from the JCA. This TransactionManager is a different instance than the one we had wired in from Spring. (Our bean had been instantiated from the arjuna environment bean). Using the JtaManager from Spring to get the transaction manager, via JNDI in the default locations, from the container ensured that we have the same transaction manager in the JTA platform used by Hibernate (JBoss App Server in this case).

Before we made this change, the application TransactionManager was in a transaction with Hibernate but the transactionManager on the datasource was not participating which caused the "leak".

Using the same instance has everything working together. This has also been proven out on WebLogic using the same approach.