Announcement Announcement Module
Collapse
No announcement yet.
Can't get JTA transactions to commit Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can't get JTA transactions to commit

    Hi,

    I'm having difficulty getting JTA transactions to commit when autocommit is set false. None of the posts I could find have helped.

    I'm using Oracle 9i (XA enabled), JOTM and Hibernate 2.1.8

    Initially I found that the DataSource connections's auto commit flag was always true by default. I couldn't find a simple way to disable autocommit when using oracle.jdbc.pool.OracleDataSource so I've been using the dbcp BasicDataSource and setting the defaultAutoCommit property to false. I've also experimented using an interceptor to intercept the DataSource getConnection() method to set autocommit false.

    I couldn't spot any issues from the debug. The following was taken from a single call to my DAO, TaskDao.addTaskNow()
    Code:
    12:24:20,921 DEBUG interceptor.TransactionInterceptor Getting transaction for com.company.TaskDao.addTaskNow
    12:24:20,936 DEBUG jta.JtaTransactionManager Using transaction object [org.springframework.transaction.jta.JtaTransactionObject@1e94001]
    12:24:20,936 DEBUG jta.JtaTransactionManager Creating new transaction with name [com.company.TaskDao.addTaskNow]
    12:24:20,936 DEBUG jta.JtaTransactionManager Beginning JTA transaction org.springframework.transaction.jta.JtaTransactionObject@1e94001
    12:24:20,936 DEBUG support.TransactionSynchronizationManager Initializing transaction synchronization
    12:24:21,327 DEBUG support.TransactionSynchronizationManager Bound value [org.springframework.jdbc.datasource.ConnectionHolder@ae1393] for key [org.apache.commons.dbcp.BasicDataSource@36ae83] to thread [main]
    12:24:21,327 DEBUG support.TransactionSynchronizationManager Bound value [org.springframework.jdbc.datasource.ConnectionHolder@871e65] for key [org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy@12ea1dd] to thread [main]
    12:24:21,327 DEBUG support.TransactionSynchronizationManager Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@871e65] for key [org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy@12ea1dd] bound to thread [main]
    12:24:21,514 DEBUG support.TransactionSynchronizationManager Bound value [org.springframework.orm.hibernate.SessionHolder@161509b] for key [net.sf.hibernate.impl.SessionFactoryImpl@dcb6b4] to thread [main]
    12:24:21,514 DEBUG support.TransactionSynchronizationManager Retrieved value [org.springframework.orm.hibernate.SessionHolder@161509b] for key [net.sf.hibernate.impl.SessionFactoryImpl@dcb6b4] bound to thread [main]
    12:24:21,530 DEBUG support.TransactionSynchronizationManager Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@ae1393] for key [org.apache.commons.dbcp.BasicDataSource@36ae83] bound to thread [main]
    Hibernate: select VEC_ACTION_ID_SEQ.nextval from dual
    12:24:21,608 DEBUG support.TransactionSynchronizationManager Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@ae1393] for key [org.apache.commons.dbcp.BasicDataSource@36ae83] bound to thread [main]
    12:24:21,702 DEBUG interceptor.TransactionInterceptor Invoking commit for transaction on com.company.TaskDao.addTaskNow
    12:24:21,702 DEBUG jta.JtaTransactionManager Triggering beforeCommit synchronization
    Hibernate: insert into VEC_ACTION (CASEID, CASECODE, ACTIVITYID, USERID, USERCODE, TYPE, CREATEDATE, CREATETIME, DUEDATE, FIRSTDATE, FIRSTTIME, LASTDATE, LASTTIME, ORIGINALDATE, ORIGINALTIME, SERVICEDATE, SERVICETIME, PRIORITY, TERMINATOR, DIARYTEXT, ACTIONTEXT, DIARYTEXT1, DIARYTEXT2, ESCDATE, ESCTIME, ESCUSERID, ESCACTIVITYID, CALENDAR, CONTEXT, BLOBID, BLOBTYPE, MASTER_CASEID, CASETITLE, DIARYTEXT3, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    12:24:21,717 DEBUG support.TransactionSynchronizationManager Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@ae1393] for key [org.apache.commons.dbcp.BasicDataSource@36ae83] bound to thread [main]
    12:24:21,717 DEBUG jta.JtaTransactionManager Triggering beforeCompletion synchronization
    12:24:21,717 DEBUG support.TransactionSynchronizationManager Removed value [org.springframework.orm.hibernate.SessionHolder@161509b] for key [net.sf.hibernate.impl.SessionFactoryImpl@dcb6b4] from thread [main]
    12:24:21,749 DEBUG support.TransactionSynchronizationManager Removed value [org.springframework.jdbc.datasource.ConnectionHolder@871e65] for key [org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy@12ea1dd] from thread [main]
    12:24:21,749 DEBUG support.TransactionSynchronizationManager Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@ae1393] for key [org.apache.commons.dbcp.BasicDataSource@36ae83] bound to thread [main]
    12:24:21,749 DEBUG jta.JtaTransactionManager Initiating transaction commit
    12:24:21,780 DEBUG jta.JtaTransactionManager Committing JTA transaction org.springframework.transaction.jta.JtaTransactionObject@1e94001
    12:24:21,780 DEBUG jta.JtaTransactionManager Triggering afterCompletion synchronization
    12:24:21,780 DEBUG support.TransactionSynchronizationManager Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@ae1393] for key [org.apache.commons.dbcp.BasicDataSource@36ae83] bound to thread [main]
    12:24:21,796 DEBUG support.TransactionSynchronizationManager Removed value [org.springframework.jdbc.datasource.ConnectionHolder@ae1393] for key [org.apache.commons.dbcp.BasicDataSource@36ae83] from thread [main]
    12:24:21,811 DEBUG support.TransactionSynchronizationManager Clearing transaction synchronization
    My datasource configuration is as follows
    Code:
    <bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName">
            <value>oracle.jdbc.driver.OracleDriver</value>
        </property>
    
        <property name="username"><value>unittest</value></property>
        <property name="password"><value>*****</value></property>
        <property name="url"><value>jdbc&#58;oracle&#58;thin&#58;@mors&#58;1521&#58;ORCL9I</value></property>
    
        <property name="defaultAutoCommit"><value>false</value></property>
    </bean>
    
    <bean id="theDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <property name="targetDataSource"><ref local="dbcpDataSource"/></property>
    </bean>
    My DAO configuration
    Code:
    <bean id="testDao" lazy-init="true"
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionAttributes">
            <props>
                <prop key="addTask">PROPAGATION_REQUIRED, -Exception</prop>
                <prop key="addTaskNow">PROPAGATION_REQUIRES_NEW, -Exception</prop>
                <prop key="deleteAllTasks">PROPAGATION_REQUIRED, -Exception</prop>
                <prop key="getTasks">PROPAGATION_REQUIRED, -Exception</prop>
            </props>
        </property>
        <property name="transactionManager">
            <ref bean="transactionManager"/>
        </property>
        <property name="target">
            <bean class="com.company.TaskDaoImpl"/>
        </property>
        <property name="proxyInterfaces">
            <list>
                <value>com.company.TaskDao</value>
            </list>
        </property>
    </bean>
    My transaction manager configuration
    Code:
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="userTransaction">
            <bean class="org.springframework.transaction.jta.JotmFactoryBean"/>
        </property>
    </bean>
    My hibernate session factory config
    Code:
    <bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
        <property name="nativeJdbcExtractor">
            <bean class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor"/>
        </property>
    </bean>
    
    <bean id="oracleSessionFactory" lazy-init="false"
          class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
        <property name="lobHandler"><ref local="oracleLobHandler"/></property>
        <property name="mappingResources">
            <list>
                <value>/com/company/Task.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
                <prop key="hibernate.transaction.manager_lookup_class">net.sf.hibernate.transaction.JOTMTransactionManagerLookup</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.jdbc.use_streams_for_binary">true</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.connection.pool_size">20</prop>
                <!-- The hibernate 'hibernate.connection.autocommit' property didn't 
                     have any effect on the value of the Connection autocommit flag. -->
                <!--prop key="hibernate.connection.autocommit">false</prop-->
                <prop key="hibernate.statement_cache.size">25</prop>
                <prop key="hibernate.query.substitutions"> true 1, false 0, yes 'Y', no 'N'</prop>
                <prop key="hibernate.query.imports">net.sf.hibernate.test, net.sf.hibernate.eg</prop>
                <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
                <prop key="hibernate.connection.inactivity-timeout">36000</prop>
                <!--prop key="hibernate.transaction.factory_class">net.sf.hibernate.transaction.JTATransactionFactory</prop-->
            </props>
        </property>
        <property name="dataSource">
            <ref bean="vectusDataSource"/>
        </property>
    </bean>
    Any help would be greatly appreciated.

    TIA.

  • #2
    I might be wrong here but if you using the JTATransactionManager you shouldn't set the transaction manager lookup on the HibernateSessionFactory as Spring implementation will delegate to the approapriate TM.
    I think you run into problems by specifing the transaction manager twice - see the javadoc for JtaTransactionManager:
    Synchronization is also leveraged for transactional cache handling with Hibernate. Therefore, as long as JtaTransactionManager drives the JTA transactions, there is no need to configure Hibernate's JTATransaction strategy or a container-specific Hibernate TransactionManagerLookup. However, certain JTA implementations are restrictive in terms of what JDBC calls they allow after transaction completion, complaining even on close calls: In that case, it is indeed necessary to configure a Hibernate TransactionManagerLookup, potentially via Spring's LocalSessionFactoryBean.

    If JtaTransactionManager participates in an existing JTA transaction, e.g. from EJB CMT, synchronization will be triggered on finishing the nested transaction, before passing transaction control back to the J2EE container. In this case, a container-specific Hibernate TransactionManagerLookup is the only way to achieve exact afterCompletion callbacks for transactional cache handling with Hibernate.

    Comment


    • #3
      Hi costin. I tried removing the hibernate hibernate.transaction.manager_lookup_class property from the configuration but it didn't fix it.

      Comment


      • #4
        Since JTA wasn't working for me I switched transaction managers (I've only one datasource in my test). After the test ran okay with the DataSourceTransactionManager I switched back to the JtaTransactionManager. Now the JTA test works :? At least it will work until I run my 'real' application and then the test starts to fail again too. I'm stuck for an explanation. Any ideas?

        Comment


        • #5
          Some configuration cache ?

          Comment


          • #6
            Websphere JTATransactionManager + Hibernate - Rollback Issue

            Hi..I'm using Hibernate 3.0 and Spring 1.2. My transactions are declaratively managed by Spring using JTATransactionManager. My service (through a proxy) calls various DAOs to insert values into different tables (in different DBs). But if there is an exception (be it Runtime / Checked), my transaction is not rolling back...

            here is my spring configiguration,

            HTML Code:
            <beans>
            	
            	<!-- Datasources -->
            	<bean id="ccssDatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
              		<property name="jndiName" value="jdbc/ccssdb"/>
              	</bean>
              	<!-- Datasources -->
              	
              	<!-- Hibernate session factories -->
            	<bean id="ccssSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
            		<property name="dataSource" ref="ccssDatasource"/>
            		<property name="mappingResources">
            			<list>
            				<value>/com/mmm/ccss/core/domain/hbm/AVSCode.hbm.xml</value>
            				<value>/com/mmm/ccss/core/domain/hbm/Country.hbm.xml</value>
            			</list>
            		</property>
            		<property name="hibernateProperties">
            			<props>
            				<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
            				<prop key="hibernate.show_sql">true</prop>
            				<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop> 
            				<prop key="hibernate.connection.autocommit">false</prop> 
            			</props>
            		</property>
            	</bean>
              	<!-- Hibernate session factories -->
              	
              	<!-- Transaction manager configuration -->
              	<bean id="wsJtaTm" class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean" />
              	
            	<bean id="ccssTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
            		 <property name="transactionManager" ref="wsJtaTm" /> 
            	</bean>
              	<!-- Transaction manager configuration -->
              	
              	<!-- Application beans -->
              	<bean id="ccssLogger" class="com.mmm.ccss.core.util.CCSSLogger" />
              	
            
            	<bean id="customerService" class="com.mmm.ccss.core.service.CustomerService" singleton="true">
            		<property name="customerDAO"><ref bean="customerDAO"/></property>
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            	
            	<bean id="paymentService" class="com.mmm.ccss.core.service.PaymentService" singleton="true">
            		<property name="paymentDAO"><ref bean="paymentDAO"/></property>
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            
            		
            	<bean id="authorizationServiceTarget" class="com.mmm.ccss.core.service.AuthorizationService" singleton="true" >
            		<property name="transmissionDAO"><ref bean="transmissionDAO"/></property>
            		<property name="configurationDAO"><ref bean="configurationDAO"/></property>
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            	
            	<bean id="authorizationService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
            	   <property name="transactionManager"><ref bean="ccssTransactionManager"/></property>
            	   <property name="target" ref="authorizationServiceTarget" />
            	   <property name="transactionAttributes" >
            			<props>
            		      <prop key="saveDetails">PROPAGATION_REQUIRED,-CCSSException</prop>
            		      <prop key="savePayment">PROPAGATION_REQUIRED,-CCSSException</prop>
            		    </props>
            	  </property>
            	  <property name="proxyTargetClass" value="true" />
            	</bean>
            	
            	<bean id="customerDAO" class="com.mmm.ccss.core.dao.HibernateCustomerDAO" >
            		<property name="sessionFactory"><ref bean="ccssSessionFactory"/></property>	
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            
            	<bean id="transmissionDAO" class="com.mmm.ccss.core.dao.HibernateTransmissionDAO" >
            		<property name="sessionFactory"><ref bean="ccssSessionFactory"/></property>	
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            
            	<bean id="creditCardDAO" class="com.mmm.ccss.core.dao.HibernateCreditCardDAO" >
            		<property name="sessionFactory"><ref bean="ccssSessionFactory"/></property>	
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            
            	<bean id="creditCardAddlDAO" class="com.mmm.ccss.core.dao.HibernateCreditCardAddlDAO" >
            		<property name="sessionFactory"><ref bean="ccssSessionFactory"/></property>	
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            
            	<bean id="configurationDAO" class="com.mmm.ccss.core.dao.HibernateConfigurationDAO" >
            		<property name="sessionFactory"><ref bean="ccssSessionFactory"/></property>	
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            
            	<bean id="paymentDAO" class="com.mmm.ccss.core.dao.HibernatePaymentDAO" >
            		<property name="sessionFactory"><ref bean="ccssSessionFactory"/></property>	
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            	
            	<bean id="merchantDAO" class="com.mmm.ccss.core.dao.HibernateMerchantDAO" >
            		<property name="sessionFactory"><ref bean="ccssSessionFactory"/></property>	
            		<property name="logger"><ref bean="ccssLogger"/></property>
            	</bean>
            	<!-- Application beans -->
            	
            </beans>
            I save the objects using getHibernateTemplate().saveOrUpdate(Obj). Everything is saved and commited fine. But incase of any exceptions, they are not rolling back..

            Pls let me know, where my issue is..

            Comment


            • #7
              Make sure you are using
              authorizationService for data access. Your declaration states that only saveDetails and savePayment should be wrapped
              in a transaction and and they should be rolledback only for
              CCSSException
              & subclasses exceptions.

              Comment


              • #8
                JTATransaction not rolling back

                I'm invoking the data access methods through "authorizationService". I get this bean through spring in a delegate class that is in my web tier. My "saveDetails" method invokes different service classes which have different DAOs in them. But only my "authorizationService" is intercepted by a proxy. So i assume that whatever data access is happening inside my "saveDetails" method should be in a transaction block. But, i see that Hibernate commits each database call then and there instead of waiting for the saveDetails method to complete. I even threw a NullPointer exception inside saveDetails method to see, if it had any effect..but no luck..

                I'm just using getHibernateTemplate().save in my DAO class. Should I configure something extra in my spring configuration to let hibernate know that all the sessions should be bound to one transaction..

                Thanks for looking in to this..

                Comment

                Working...
                X