Facing a strange problem here, below is the configuration i am using:
1. Apache Tomcat 6.0.26
2. mySql
3. Spring framework+ Hibernate
We have used JOTM for transaction management
<bean id="jotm"
class="org.springframework.transaction.jta.JotmFactoryBean" />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
< property name="userTransaction" ref="jotm" />
</bean>
The problem is that i have one service which creates and entity on my local DB and then calls a web service on failiure of which the created entity in local DB should be rolled back. On failure of the web service call i am throwing RunTimeException which should ideally rollback the transaction as per mentioned in the spring configuration file. However this is not happening. Instead of JOTM if i am using Hibernate transaction manager it is rolling back the transaction. Can someone please throw some light on if i am missing out on anything while implementing through JOTM.
Appreciate the help in advance,
Vaibhav
Related
We have an application developed using Spring 3.1.1 and Hibernate 3.6.10, and uses Oracle 11g as database.
The application looks-up the datasource using JNDI, and uses a org.springframework.orm.hibernate3.HibernateTransactionManager.
And spring configuration file contains:
<jee:jndi-lookup jndi-name="jdbc/ds"
id="dataSource" proxy-interface="javax.sql.DataSource"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
....
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
We use Tomcat in development machines, but the application is deployed on Weblogic 11 for production.
The problem is in Weblogic datasource.log file, the following message is logged:
<autoCommit=true,enabled=true,isXA=true,isJTS=false,vendorID=0,connUsed=false,doInit=false,'null',destroyed=false,poolname=life_rac,appname=null,moduleName=null,connectTime=45,dirtyIsolationLevel=false,initialIsolationLevel=2,infected=false,lastSuccessfulConnectionUse=1531636426817,secondsToTrustAnIdlePoolConnection=10,currentUser=java.lang.Exception
at weblogic.jdbc.common.internal.ConnectionEnv.setup(ConnectionEnv.java:356)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:364)
at weblogic.common.resourcepool.ResourcePoolImpl.reserveResource(ResourcePoolImpl.java:330)
...
Now we are worried about that autoCommit=true in the log messages, cause it seems that in some cases the first DML queries are committed when they shall not, especially when the Weblogic is stopped due to some problems (for example power-loss).
I shall mention that the data-source defined in Weblogic Server is a XA-Datasource.
Is there a way to change default configuration of autoCommit to false?
As we have just one database, and no other transactional resources, I believe we change can the datasource to a non-XA one, without any impact. Am I correct?
And we need to change the configuration so it works both on Weblogic and Tomcat (adding some configuration to Tomcat -such as adding a transaction manager- is okay).
WebLogic Server 11g allows you to create and deploy a jdbc interceptor class. This documentation will help to write the class. Each time a connection is created, your interceptor will be called and you will be able to set the auto commit property to false.
This way is deprecated in 11g. 12c uses a Connection Initialization Callback.
We are using JPA (Hibernate 4) with Spring 4 managing the JTA transactions. Since there are parts of the application using JDBC to access the database as well, we need to make sure JDBC and JPA join the same transaction to see what the other changed before commit.
You can find a test case for these questions on GitHub https://github.com/abenneke/sandbox/tree/master/spring-hibernate4-transaction
To have JDBC and JPA join the same transaction and see the changes the other made, we had to use the TransactionAwareDataSourceProxy for Hibernate/JPA as well. With all the other transaction configuration around, this however seems to be redundant. Did we miss something? Or is this the suggested way to achieve the requirement?
Thank you!
I think you can achieve the same outcome with much less configuration hassle if you stock to Hibernate and your JTA DataSource while you use the Session.doWork for your JDBC code.
You don't need TransactionAwareDataSourceProxy, since you want to use Transaction services anyway and not call DAO classes outside of a transactional service.
You need to add:
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
and make sure you supply it to testEntityManager
<bean id="testEntityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="testDataSource">
...
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
Update
In one application we developed recently we too mixed JPA and JDBCTemplate and it worked nicely because Bitronix PoolingDataSource was instructed to always return the same connection for the current running thread.
For this you have to set the following Bitronix property:
shareTransactionConnections=true
How to know if my particular flow or API is getting executed in one transaction or not ?
I am using the JPATransactionManager
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
I am using #Transactional annotation at API to declare the transactional boundaries.
I am trying hard to find out clear transaction boundaries in my application and know when particular transaction is getting started, when particular transaction is ended.. I also tried logs for JPATranscationManager at Trace level but didn't help much.
Question
How do I configure a JtaTransactionManager object with allowCustomIsolationLevels set to true via Spring such that the Spring configuration can be used across multiple application servers?
Background:
I have an application that is currently running out of JBossAS and I'm trying to get it to run in WebSphere. The only issue I'm currently having is getting the correct JTA Transaction Manager injected with the proper settings.
Here's the old setting
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName">
<value>java:/TransactionManager</value>
</property>
<property name="allowCustomIsolationLevels" value="true" />
</bean>
This worked since JBossAS has it's JTA Transaction Manager defined at JNDI location java:/TransactionManager. However, WebSphere does not have the same JNDI location.
Spring 2.5.x provides a way to get the JTA Transaction Manager in a generalized way.
<tx:jta-transaction-manager />
This gets the JtaTransactionManager object and defines it as a bean with the id transactionManager.
I looked in the Spring TX schema, but the only setting available is to set a specific isolation level, but not just to allow custom levels to be used (as defined elsewhere). How do I set the allowCustomIsolationLevels property using the tx:jta-transaction-manager tag?
Transaction Managers and Websphere:
Websphere does not use the typical jndi standard when supplying the transaction manager. Spring has worked around this by providing the org.springframework.transaction.jta.WebSphereUowTransactionManager that you can use to lookup the websphere transaction manager.
Datasource and Isolation Levels
You typically cannot change the isolation level of a datasource and I know you cannot change it when connecting from websphere to DB2 database (it's set as a parameter on the datasource configuration). The allowCustomIsolationLevels flag lets you select different data sources for different requested isolation levels..
See here and here
I have one applicationContext.xml file, and it has two org.springframework.orm.jpa.JpaTransactionManager (each with its own persistence unit, different databases) configured in a Spring middleware custom application.
I want to use annotation based transactions (#Transactional), to not mess around with TransactionStatus commit, save, and rollback.
A coworker mentioned that something gets confused doing this when there are multiple transaction managers, even though the context file is set configured correctly (the references go to the correct persistence unit.
Anyone ever see an issue?
In your config, would you have two transaction managers?
Would you have txManager1 and txManager2?
That's what I have with JPA, two different Spring beans that are transaction managers.
I guess you have 2 choices
If your use-cases never require updates to both databases within the same transaction, then you can use two JpaTransactionManagers, but I'm not sure you will be able to use the #Transactional approach? In this case, you would need to fallback on the older mechanism of using a simple TransactionProxyFactoryBean to define transaction boundaries, eg:
<bean id="firstRealService" class="com.acme.FirstServiceImpl"/>
<bean id="firstService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="firstJpaTm"/>
<property name="target" ref="firstRealService"/>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- similar for your second service -->
If you are require a transaction spanning both databases, then you will need to use a JTA transaction manager. The API states:
This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access. JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure your JPA provider accordingly in order to make it participate in JTA transactions.
What this means is that you will need to provide a JTA transaction manager. In our application, we use config similar to the following:
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="appserver/jndi/path" />
</bean>
If you are deploying within an appserver, then the spring JtaTransactionManager needs to do a lookup to the real XA-compliant JTA transaction manager provided by the appserver. However, you can also use a standalone JTA transaction manager (but I haven't tried this myself yet)
As for configuring the Jpa persistence provider, I'm not that familiar. What JPA persistence provider are you using?
The code above is based on our approach, where we were using native Hibernate as opposed to Hibernate's JPA implementation. In this case, we were able to get rid of the two HibernateTransactionManager beans, and simply ensure that both SessionFactories were injected with the same JTA TM, and then use the tx:annotation-driven element.
Hope this helps
The only situation in which you can have two Spring transaction managers is if you never have both transactions open at one time. This is not intrinsically to do with distributed transactions - the same restrictions apply even if you want the two datasources to have completely separate (but potentially overlapping in time) transaction lifecyles.
Internally Spring's transaction managers all use Spring's TransactionSynchronizationManager which keeps a bunch of critical state in static ThreadLocal variables, so transaction managers are guaranteed to stomp all over each other's state.