Results 1 to 4 of 4

Thread: HibernateCursorItemReader & Atomikos

  1. #1
    Join Date
    Oct 2008
    Posts
    2

    Default HibernateCursorItemReader & Atomikos

    Hi,

    I have defined a job that reads from a MySQL database using HibernateCursorItemReader & writes each item to a JMS queue using an ItemWriterAdapter delegating to a custom bean method. XA integrity is required so I'm using Atomikos as the transanctionManager.
    I am running into trouble when accessing the ScrollableResultSet next() in the reader. It appears there is no transaction to join..

    Code:
    INFO  [SimpleJobLauncher] Job: [org.springframework.batch.core.configuration.support.ClassPathXmlApplicationContextJo
    bFactory$ContextClosingJob] failed with the following parameters: [{}{}{}{}]
    com.atomikos.datasource.ResourceException: Error in resume() for XID: pmc_tm0001100046pmc_tm1 with errorCode -9
    at com.atomikos.datasource.xa.XAResourceTransaction.resume(Unknown Source)
    at com.atomikos.jdbc.ConnectionProxy.invoke(Unknown Source)
    at $Proxy21.prepareStatement(Unknown Source)java:505)
    My JTA debug indicates that transactions are being created/commited for each of the job respository meta data calls.. is this correct behaviour?

    If you haven't already guessed I'm new to Spring batch

    I'm sure I've missed something in my config, can anyone spot anything obvious?

    Any help/pointers much appreciated!

    Code:
     
    <!-- ================= Batch Config ================= -->
    
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" >
        <property name="transactionManager" ref="transactionManager" />
        <property name="isolationLevelForCreate" value="ISOLATION_DEFAULT" />
    </bean>
    
    <bean id="myJob" class="org.springframework.batch.core.job.SimpleJob" >
        <property name="jobRepository" ref="jobRepository" />
        <property name="steps">
            <list>
                <bean id="myStep" class="org.springframework.batch.core.step.item.SimpleStepFactoryBean">
                    <property name="itemReader" ref="hibernateItemReader" />
                    <property name="itemWriter" ref="jmsEventWriter" />
                    <property name="transactionManager" ref="transactionManager" />
    		<property name="jobRepository" ref="jobRepository" />
    		<property name="commitInterval" value="1" />
                </bean>
            </list>
        </property>
    </bean>
    
    <bean id="hibernateItemReader" class="org.springframework.batch.item.database.HibernateCursorItemReader">
        <property name="sessionFactory" ref="hibernateSessionFactory" />
        <property name="useStatelessSession" value="true" />
        <property name="queryString" value="from Item" /> 
    </bean>
    
    <bean id="jmsEventWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
        <property name="targetObject" ref="jmsProcessor" />
        <property name="targetMethod" value="sendJMS" />
    </bean>
    
    <!-- ================= Atomikos Config  ================= -->
    
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
    		init-method="init" destroy-method="close">
        <property name="forceShutdown" value="true" />
        <property name="transactionTimeout" value="300" /> 
        <property name="startupTransactionService" value="true"/>        
    </bean>
    	
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"/>
    		
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="atomikosTransactionManager"/>
        <property name="userTransaction" ref="atomikosUserTransaction"/>
    </bean>
    
    <!-- ================= Hibernate Config  ================= -->
    <properties>
    <property name="hibernate.connection.release_mode" value="after_transaction" />
    <property name="hibernate.transaction.factory.class" value="org.hibernate.transaction.JTATransactionFactory"/>
    <property name="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup"/>
    <property name="hibernate.jdbc.use_scrollable_resultset" value="true" />
    </properties>
    
    <!-- entityManagerFactory is a JPA EntityManager, so I access the underlying  HibernateSessionFactory like this -->
    
    <bean id="hibernateSessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory" />

  2. #2
    Join Date
    Aug 2004
    Posts
    1,107

    Default

    Couple of questions. Can you post the dataSource you are using for the JobRepository? Are you using MySQL for the job repository as well? What JMS provider are you using?

    You would need a com.atomikos.jdbc.AtomikosDataSourceBean defined for the job repository and a com.atomikos.jms.QueueConnectionFactoryBean for your JMS provider. The configuration options for MySQL are still listed as ToDO on the Atomikos site so this might be an issue.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  3. #3
    Join Date
    Oct 2008
    Posts
    2

    Default

    I had been using MySQL for the JobRepository (com.mysql.jdbc.jdbc2.optional.MysqlXADataSource) but have switched to a MapJobRepository for now while I resolve this issue. I was getting the same error but thought it would simplify things. It was working fine in the sense that meta data was persisted, so I'm happy with that side of things.

    My existing app uses the above MySQL datasource and the Atomikos config to wrap JPAEntityManager-JMSTemplate in an XA.
    I have found that if I wrap the whole jobLauncher.run call in an XA, I don't get the error.. so I'm thinking there has to be something within the framework..

    Would the JTA/Batch logs be of any use?

  4. #4
    Join Date
    Aug 2004
    Posts
    1,107

    Default

    I'm not sure why you are bothering with XA in the first place since your job isn't restartable - in case of failure you would have to adjust things manually anyway. To me it would make sense wrapping the Job Repository and the Writer in an XA transaction to be able to provide consistent restarts. You could also include the reader as well in the XA transaction. Maybe I'm missing something in what you are trying to do in which case the complete configuration might help.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •