Announcement Announcement Module
Collapse
No announcement yet.
A transaction in onWriteError is not being committed to database (JDBC) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • A transaction in onWriteError is not being committed to database (JDBC)

    This is related to SpringBatch but the issue might be Spring Core so let me know if I need to re-post it somewhere else. I am facing seems to be related to JDBC and Spring Core so posting it here.

    I ahve a job that is using a CompositeItemWriter which has a delegate writer which uses JDBC Template to persist data in the Oracle db. I have implemented a StepListener which has overridden the callback method OnWriteError ((of ItemWriterListener)) and in this method deletes any rows inserted by the writer before that error/exception occurred. I am using same dataSource for all activities. What happening is that the implementation inside the OnWriterError tries to delete the data inserted by the writer but as it is running under the same transaction as the writer, the deletion is rolled back. I have tried to change this behaviour by configuring the transaction attributed and proxying my Dao class. Configurations are as fellows:

    The job:
    Code:
    <batch:job id="CounterFileProcessJob" job-repository="jobRepository"
    		incrementer="jobParamatersIncrementer">
    		<batch:step id="CounterFileProcessJobStep" >
    			<batch:tasklet transaction-manager="jobRepository-transactionManager">
    				<batch:chunk reader="tpiAccumulatorInboundReader"
    					processor="tpiAccumulatorInboundProcessor" writer="tpiAccumumlatorCompositeWriter"
    					commit-interval="1">
    					<batch:streams>
    						<batch:stream ref="tpiAccumulatorEX07InboundWriter" />
    						<batch:stream ref="consumptionJDBCWriter" />
    					</batch:streams>
    				</batch:chunk>
    				<batch:listeners>
    					<batch:listener ref="coreStepListener" />
    					<batch:listener ref="consumptionJDBCWriter" />
    				</batch:listeners>
    			</batch:tasklet>
    		</batch:step>
    </batch:job>
    The writers:
    Code:
    <bean id="tpiAccumumlatorCompositeWriter" scope="step"
    		class="org.hphc.batch.tpi.accumulator.inbound.OHBSCounterCompositeWriter">
    		<property name="delegates">
    			<list>
    				<ref bean="tpiAccumulatorEX07InboundWriter" />
    				<ref bean="consumptionJDBCWriter" />
    			</list>
    		</property>
    </bean>
    
    		
    <bean id="consumptionJDBCWriter"  scope="step"
    	class="org.hphc.batch.tpi.accumulator.inbound.ConsumptionJDBCWriter">
    		<property name="daoFactory" ref="daoFactory" />
    </bean>

    The Listener:
    Code:
    	
    <bean id="coreStepListener" scope="step"
    		class="org.hphc.batch.tpi.accumulator.inbound.listener.CoreStepListener">
    		<property name="fileName" value="#{jobParameters['outputFileName']}" />
    		<property name="fileFormatSpecificationFactory" ref="fileFormatSpecificationFactory" />
    		<property name="lineAggregator" ref="ex07LineAggregator" />
    		<property name="cleanUpDao" ref="pcleanUpDao" />
    </bean>
    The transaction proxy setting (the clean* method is the one in need of a new transaction):
    Code:
    	<bean id="daoFactory"
    		class="org.hphc.batch.tpi.accumulator.inbound.dao.impl.DAOFactoryImpl">
    		<property name="migrationAccumulationDao" ref="pMigrationAccumulationDao" />
    	</bean>
    
    	<bean id="pMigrationAccumulationDao"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="transactionManager" />
    		<property name="target" ref="migrationAccumulationDao" />
    		<property name="proxyTargetClass" value="true" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="clean*">PROPAGATION_REQUIRES_NEW</prop>
    				<prop key="save*">PROPAGATION_REQUIRED, -Exception</prop>
    			</props>
    		</property>
    	</bean>


    OnWriterError method (this deletion isn't committed as the earlier/parent transaction is marked for rolled back even if this method is REQUIRES_NEW):
    Code:
    public void onWriteError(Exception exception,
    			List<? extends List<CounterRecord>> items) {
    		pMigrationAccumulationDao.cleanMigrationAccumulationsOnError(batchId);
    	}


    Even if I set PROPAGATION_REQUIRES_NEW attribute for above 'clean' method, it does not work and my deletion query is rolled back too.

    My DAO (pMigrationAccumulationDao) is extending JDBCDaoSupport. Please advise that what am I doing wrong? Thanks a lot.

  • #2
    what are you trying to achieve actually? why trying to delete the rows the item writer inserts on an error? won't simply rolling back be enough?

    Comment

    Working...
    X