Announcement Announcement Module
Collapse
No announcement yet.
XA transactions in Spring Batch Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • XA transactions in Spring Batch

    Hello,

    I need to configure XA Transactions in Spring Batch

    I'm using

    Spring 3.1
    Spring Batch 2.1.8
    Hibernate 3.6.9 Final



    I have one project with 2 database but I need help for configuration with 2 database because I don't find documentation of this.'

    How transactionality Spring Batch handles when you have two database?
    Because I'm having project with two database in service transactional but when The application has error, this only make rollback of one DataBase.
    I need to use transactional XA for this problem.
    Any help please?


    My configuration now

    DataSource.xml

    .
    .
    .

    < bean id="dataSourceA" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    < property name="driverClassName">
    < value>${ipdatabase.connection.driver}</value>
    < /property>
    < property name="url">
    < value>${ipdatabase.connection.url}</value>
    < /property>
    < property name="username">
    < value>${ipdatabase.connection.username}</value>
    < /property>
    < property name="password">
    < value>${ipdatabase.connection.password}</value>
    < /property>
    </bean>

    <bean id="dataSourceB" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName">
    <value>${extdatabase.connection.driver}</value>
    </property>
    <property name="url">
    <value>${extdatabase.connection.url}</value>
    </property>
    <property name="username">
    <value>${extdatabase.connection.username}</value>
    </property>
    <property name="password">
    <value>${extdatabase.connection.password}</value>
    </property>
    </bean>


    Hibernate3.xml

    .
    .
    .

    <!-- SessionFactory Configuration -->
    <bean id="abstractSessionFactoryA" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean" abstract="true">
    <property name="dataSource" ref="dataSourceA" />
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">
    ${iphibernate.dialect}
    </prop>
    <prop key="hibernate.show_sql">
    ${iphibernate.show_sql}
    </prop>
    <prop key="hibernate.generate_statistics">
    ${iphibernate.generate_statistics}
    </prop>

    <!-- ehCache configuration -->
    <prop key="hibernate.cache.use_second_level_cache">
    ${iphibernate.cache.use_second_level_cache}
    </prop>
    <prop key="hibernate.cache.use_query_cache">
    ${iphibernate.cache.use_query_cache}
    </prop>
    <prop key="hibernate.cache.region.factory_class">
    ${iphibernate.cache.region.factory_class}
    </prop>
    <prop key="net.sf.ehcache.configurationResourceName">
    ${iphibernate.configurationResourceName}
    </prop>
    </props>
    </property>
    </bean>

    <bean id="sessionFactoryA" parent="abstractSessionFactoryA">
    <property name="configLocations">
    <list>
    <value>classpath:com/production/module/massive/configuration/hbm/massive-core-hbm.cfg.xml</value>
    <value>classpath:com/production/module/massive/configuration/hbm/massive-ecommerceint-hbm.cfg.xml</value>
    </list>
    </property>
    </bean>


    <bean id="abstractSessionFactoryB" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean" abstract="true">
    <property name="dataSource" ref="dataSourceB" />
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">
    ${iphibernate.dialect}
    </prop>
    <prop key="hibernate.show_sql">
    ${iphibernate.show_sql}
    </prop>
    <prop key="hibernate.generate_statistics">
    ${iphibernate.generate_statistics}
    </prop>

    <!-- ehCache configuration -->
    <prop key="hibernate.cache.use_second_level_cache">
    ${exthibernate.cache.use_second_level_cache}
    </prop>
    <prop key="hibernate.cache.use_query_cache">
    ${exthibernate.cache.use_query_cache}
    </prop>
    <prop key="hibernate.cache.region.factory_class">
    ${exthibernate.cache.region.factory_class}
    </prop>
    <prop key="net.sf.ehcache.configurationResourceName">
    ${exthibernate.configurationResourceName}
    </prop>
    </props>
    </property>
    </bean>

    <bean id="sessionFactoryB" parent="abstractSessionFactoryB">
    <property name="configLocations">
    <list>
    <value>classpath:com/production/module/massive/configuration/hbm/massive-hbm.cfg.xml</value>
    </list>
    </property>
    </bean>


    Service.xml
    (I have 2 transaction Manager. Is ok??)

    .
    .
    .

    <bean id="transactionManagerA" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
    <property name="sessionFactory" ref="sessionFactoryA" />
    </bean>

    <bean id="transactionManagerB" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
    <property name="sessionFactory" ref="sessionFactoryB" />
    </bean>

    <tx:advice id="txAdviceA" transaction-manager="transactionManagerA">
    <tx:attributes>
    <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
    <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
    <tx:method name="delete*" propagation="REQUIRED" />
    <tx:method name="get*" propagation="REQUIRED" read-only="true" />
    <tx:method name="find*" propagation="REQUIRED" read-only="true" />
    <tx:method name="process*" propagation="REQUIRED" rollback-for="Exception" />
    </tx:attributes>
    </tx:advice>

    <tx:advice id="txAdviceB" transaction-manager="transactionManagerB">

    <tx:attributes>
    <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
    <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
    <tx:method name="process*" propagation="REQUIRED" rollback-for="Exception" />
    <tx:method name="delete*" propagation="REQUIRED" />
    <tx:method name="get*" propagation="REQUIRED" read-only="true" />
    <tx:method name="find*" propagation="REQUIRED" read-only="true" />
    </tx:attributes>
    </tx:advice>

    <aop:config>
    <aopointcut id="serviceTxConfiguration" expression="execution(* com.production.module.batch.facade..*.*(..))" />
    <aop:advisor advice-ref="txAdviceA" pointcut-ref="serviceTxConfiguration" />
    <aop:advisor advice-ref="txAdviceB" pointcut-ref="serviceTxConfiguration" />
    </aop:config>


    Spring-batch.xml
    (This well set up job-repository with just a transaction-manager, how it behaves with two transactions? . How it should be ?)


    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/batch"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schem...-beans-3.0.xsd
    http://www.springframework.org/schema/batch
    http://www.springframework.org/schema/batch/spring-batch-2.1.xsd">

    <job-repository id="jobRepository" data-source="dataSourceB" transaction-manager="transactionManagerB" isolation-level-for-create="REPEATABLE_READ" />

    <beans:bean id="jobLauncher" class="org.springframework.batch.core.launch.suppo rt.SimpleJobLauncher">
    <beansroperty name="jobRepository" ref="jobRepository" />
    </beans:bean>
    </beans:beans>




    jobs_bd.xml

    <!-- READER HEADERS -->
    <beans:bean name="cont_DBReader" id="cont_DBReader" class="org.springframework.batch.item.database.Jdb cCursorItemReader">
    <beansroperty name="dataSource" ref="dataSourceB" />
    <beansroperty
    name="sql"
    value=" select id,version,dateCreated,dateLastUpdated,createdBy,l astUpdatedBy,utilityname,accountNumber,statusValue
    from accountProductCandidateHdr
    where statusValue=? and processSource='CONT' "
    />

    <beansroperty name="preparedStatementSetter">
    <beans:bean class="com.production.module.batch.job.domain.Cand idateStatementSetter" />
    </beansroperty>

    <beansroperty name="rowMapper">
    <beans:bean class="com.production.module.batch.job.domain.Reta ilMassiveRowMapper">
    <beansroperty name="batchFacade" ref="batchFacade" />
    </beans:bean>
    </beansroperty>
    </beans:bean>
    <beans:bean id="cont_SynchronizedReaderFac" class="com.production.module.batch.job.domain.Sync hronizedJdbcCursorItemReader">
    <beansroperty name="jdbcCursorItemReader" ref="cont_DBReader"/>
    </beans:bean>

    <!-- WRITER BATCH PROCESS -->
    <beans:bean id="cont_ItemWriter" class="com.production.module.batch.job.domain.Reta ilMassiveItemWriter">
    <beansroperty name="batchFacade" ref="batchFacade" />
    </beans:bean>



    < job id = "cont_MasiveProcessJob">
    < step id="cont_massive_enroll">
    < tasklet task-executor="cont_TaskThreadExecutor" throttle-limit="${batch.throttleLimit}">
    < chunk reader="cont_SynchronizedReaderFac" writer="cont_ItemWriter" commit-interval="${batch.commitInterval}">
    <skip-policy>
    <beans:bean class="org.springframework.batch.core.step.skip.Al waysSkipItemSkipPolicy"/>
    </skip-policy>
    </chunk>
    <transaction-attributes propagation="REQUIRED" />
    </tasklet>

    <listeners>
    <listener>
    <beans:bean class="com.production.module.batch.job.ItemListene r"/>
    </listener>
    </listeners>

    < /step>
    < /job>


    RetailMassiveItemWriter.java

    batchFacade is transaccion
    this is defined in service.xml
    ( < tx:method name="process*" propagation="REQUIRED" rollback-for="Exception" /> )



    public class RetailMassiveItemWriter implements ItemWriter<AccountProductCandidateHeader> {
    protected final Log logger = LogFactory.getLog(getClass());

    private BatchFacade batchFacade;

    @Override
    public void write(List<? extends AccountProductCandidateHeader> items) throws Exception {
    for (AccountProductCandidateHeader header: items) {
    batchFacade.processMassiveAccount(header);
    }
    }

    public void setBatchFacade(BatchFacade batchFacade) {
    this.batchFacade = batchFacade;
    }
    }

    How could configure the XA with Spring Batch?
    Thanks for any help.
Working...
X