MySQL and Infinispan - JTA implementation - spring

We have an web application under Tomcat, integrated with Hibernate 4X, Spring 4X and HibernateTransactionManager as our transaction manager (currently one MySQL resource).
As part of our configuration distribution, we should integrate with Infinispan as our cache manager to store configuration with other format than in the MySQL. Meaning, not as Hibernate second level cache integration!
I managed to integrate Infinispan with Spring but now I'm facing a big problem due to the fact the MySql transaction and Infinispan must be on the same #Transactional.
I read about Spring JTA and how to integrate with Atomikos (e.g.) as our Global Transaction manager but I'm not sure if we can combine the whole entities to work together and how :(
I need to know if there's an option to work with Atomikos Spring JTA so the Infinispan will recognize this JTA implementation and will handle the MySql and Infinispan as one global transaction! (2PC)
Thanks!

At first I would suggest to configure Spring + Hibernate + JTA together. Here is a very nice tutorial. If you configured everything correctly - you should have one bean of a type TransactionManager. In above tutorial it is configured inside this block:
#Bean(initMethod = "init", destroyMethod = "close")
public TransactionManager transactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
}
Now you may configure Infinispan to use this transaction manager. The easiest way to achieve this, is to implement your own TransactionManagerLookup. This should return the transaction manager, which was created above.
Finally you have to create transactional cache, like this:
<local-cache name="transactional">
<transaction mode="FULL_XA"/>
</local-cache>
After that everything should work with the same Transaction Manager and Spring should handle everything within single #Transactional annotation.

Related

With spring boot, how does it detect a JTA environment?

I'm trying to enable JTA with spring boot so that JPA and JMS will roll back together. All docs point to http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-jta.html and it states
When a JTA environment is detected, Spring’s JtaTransactionManager
will be used to manage transactions.
What is meant by "JTA environment is detected"?
I ask because I think that is what is tripping me up. I added dependencies for Atomikos, but jmsTemplate.isSessionTransacted() returns false. I am assuming I haven't properly marked my environment as JTA. I'm running with embedded tomcat.
What I am experiencing is the database changes are being rolledback with the transaction, but not the JMS messages.
UPDATE:
The part about sessionTransacted was not related. It was my misunderstanding.
A JTA environment is detected when a supported transaction manager is on the classpath (Atomikos or Bitronix in 1.3, and also Narayana in 1.4) or because a javax.transaction.TransactionManager is available in JNDI (typically because you've deployed your Boot app to a Java EE container).
I think you have misunderstood the purpose of the sessionTransacted flag on JmsTemplate. It's used when creating a new session (Connection.createSession), however the transacted value that's passed to createSession is ignored when you're running in a JTA environment.
You can see it in the class org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration:
#ConditionalOnClass(javax.transaction.Transaction.class)
#ConditionalOnProperty(prefix = "spring.jta", value = "enabled", matchIfMissing = true)
#AutoConfigureBefore({ XADataSourceAutoConfiguration.class,
ActiveMQAutoConfiguration.class, HornetQAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
#Import({ JndiJtaConfiguration.class, BitronixJtaConfiguration.class,
AtomikosJtaConfiguration.class, NarayanaJtaConfiguration.class })
#EnableConfigurationProperties(JtaProperties.class)
public class JtaAutoConfiguration {
}
Basically you have to have the JTA API on the classpath, and at least one JTA provider (Bitronix or Atomikos, if you're not using an application server).

Spring Batch combined with Atomikos not working

I’m having trouble configuring an Tomcat – Spring Batch – Atomikos combination.
I have configured the following (I’m not mentioning the JMS configuration)
Atomikos DataSource (proxy) based on
com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory for Oracle XA datasource.
JtaTransactionManager based on
transactionManager based on com.atomikos.icatch.jta.J2eeTransactionManager
userTransaction based on
com.atomikos.icatch.jta.J2eeUserTransaction
When executing a batch job I receive the following error:
Caused by: java.lang.RuntimeException: Transaction Service Not Running?
at com.atomikos.icatch.jta.J2eeUserTransaction.checkSetup(J2eeUserTransaction.java:70)
at com.atomikos.icatch.jta.J2eeUserTransaction.getStatus(J2eeUserTransaction.java:125)
at org.springframework.transaction.jta.JtaTransactionManager.
isExistingTransaction(JtaTransactionManager.java:797)
Debugging revealed the following:
Spring Batch makes use of TaskletStep. This class uses a PlatformTransactionManager that is instantiated with a DataSourceTransactionManager? The datasource is referring to a AtomikosDataSourceBean, that seems ok.
I have several questions:
Where is this DataSourceTransactionManager coming from? I have defined a JtaTransactionManager!
I thought the AtomikosDataSourceBean acts like a proxy to connect to JtaTransactionManager. Why is Atomikos given the error “Transaction Service Not Running?”
Spring Batch: 2.1.8
Atomikos: 3.9.3

Best practice for open/get Hibernate session in Spring 4 + Hibernate 4.3.1.final

In our project we use Spring and Spring Data (for server side API service), but sometimes we do query not using Spring Data, but using JPA criteria. In order to do so we use:
#PersistenceContext
private EntityManager em;
...
CriteriaBuilder cb = em.getCriteriaBuilder();
...
From the Spring docs:
Although EntityManagerFactory instances are thread-safe, EntityManager instances are not. The injected JPA EntityManager behaves like an EntityManager fetched from an application server's JNDI environment, as defined by the JPA specification. It delegates all calls to the current transactional EntityManager, if any; otherwise, it falls back to a newly created EntityManager per operation, in effect making its usage thread-safe.
So it seems that the way we use should get the current session if exists and if not should create new one. The issue we are facing is a memory leak of this use. seems like this way opens a lot of Hibernate session and does not close them.
So for the question: What is the best practice to getCurrent/open new session in Spring with Hibernate?
Note: HibernateUtil does not have getSessionFactory() as suggested in some other posts
Thanks,
Alon

Hibernate + JdbcTemplate

I've got a project of mine in which I would like to take advantage of Hibernate to increase the speed of development for basic operations, combined with Spring's JDBC template to be able to use my own SQL queries for some specific operations and not loose control, since there are some heavy, performance demanding operations.
Is this even possible or a good idea?
Yes, it is possible. And yes, it's a good idea.
The documentation says:
For distributed transactions across multiple Hibernate session factories, simply combine JtaTransactionManager as a transaction strategy with multiple LocalSessionFactoryBean definitions. Each DAO then gets one specific SessionFactory reference passed into its corresponding bean property. If all underlying JDBC data sources are transactional container ones, a business service can demarcate transactions across any number of DAOs and any number of session factories without special regard, as long as it is using JtaTransactionManager as the strategy.
[...]
HibernateTransactionManager can export the Hibernate JDBC Connection to plain JDBC access code, for a specific DataSource. This capability allows for high-level transaction demarcation with mixed Hibernate and JDBC data access completely without JTA, if you are accessing only one database. HibernateTransactionManager automatically exposes the Hibernate transaction as a JDBC transaction if you have set up the passed-in SessionFactory with a DataSource through the dataSource property of the LocalSessionFactoryBean class. Alternatively, you can specify explicitly the DataSource for which the transactions are supposed to be exposed through the dataSource property of the HibernateTransactionManager class.
So, if you're in a full-stack Java EE container supporting JTA transactions and DataSources, use a DataSource defined in your Java EE container and a JTATransactionManager.
If you'e in a simple web container such as Tomcat, use a Spring-provided DataSource and a HibernatTransactionManager.

Transaction in Spring with datasources create in runtime

I have a problem with transaction in spring, because in my project datasources are created in runtime from side files and according to documentation:
I should inject to TransactionManager dataSource and made it visible for annotation #Transactional using <tx:annotation-driven transaction-manager="txManager"/>.
So my question is how can I do it when I want to use annotation?
First of all how are you creating the datasources at runtime.
if directly as Datasource=new datasource... I will suges use BeanDefinitionBuilder in Spring 3.2 to Create the Datasourcebean and then register it via BeanDefinitionRegistry.
and then get the bean from Spring context and it will be considered using the transaction.

Resources