I am trying to investigate what happens when an exception is throw in the writer. As per theory I was expecting a roll-back to occur and then retry the chunk setting commit size as 1. but this is not happening and i am receiving the following error.
I am using Spring Batch -JSR 352 job design. In the writer I have 3 JDBC calls. If i throw an skippable exception after 2 JDBC calls have been successfully executed , then I could find the Spring batch is not able to rollback the transaction for the chunk and retry the chunk by placing the commit size as one. I am receiving the following execption after which the entire chunk is getting skipped and we are having an chunk commit. As a result the data already written to 2 JDBC tables are getting persisted missing the 3rd table data. 20 Apr 2015 18:38:28,811 ERROR [gov.state.nextgen.in.batch.sdx.chunk.writer.SdxRcvDlyWriter.writeItems(SdxRcvDlyWriter.java:74)] - Error while writing sdxRcvRecord :Exception occured during processing at gov.state.nextgen.in.batch.sdx.bo.impl.SdxRcvDlyBoImpl.write(SdxRcvDlyBoImpl.java:125) at gov.state.nextgen.in.batch.sdx.chunk.writer.SdxRcvDlyWriter.writeItems(SdxRcvDlyWriter.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:94) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55) at java.lang.reflect.Method.invoke(Method.java:619) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) at com.sun.proxy.$Proxy18.writeItems(Unknown Source) at org.springframework.batch.jsr.item.ItemWriterAdapter.write(ItemWriterAdapter.java:55) at org.springframework.batch.core.jsr.step.item.JsrChunkProcessor.doPersist(JsrChunkProcessor.java:243) at org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor$5.doWithRetry(JsrFaultTolerantChunkProcessor.java:298) at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:263) at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:168) at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:222) at org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor.persist(JsrFaultTolerantChunkProcessor.java:348) at org.springframework.batch.core.jsr.step.item.JsrChunkProcessor.process(JsrChunkProcessor.java:114) at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75) at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271) at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77) at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368) at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) at org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState.handle(JsrStepState.java:53) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:165) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) at org.springframework.batch.core.jsr.job.flow.JsrFlowJob.doExecute(JsrFlowJob.java:82) at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304) at org.springframework.batch.core.jsr.launch.JsrJobOperator$2.run(JsrJobOperator.java:675) at java.lang.Thread.run(Thread.java:795) 20 Apr 2015 18:38:50,157 DEBUG [org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:293)] - Checking for rethrow: count=1 20 Apr 2015 18:38:52,584 DEBUG [org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:313)] - Retry failed last attempt: count=1 20 Apr 2015 18:38:53,403 DEBUG [org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor$6.recover(JsrFaultTolerantChunkProcessor.java:333)] - Skipping after failed write org.springframework.batch.core.step.item.ForceRollbackForWriteSkipException: Force rollback on skippable exception so that skipped item can be located. at org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor$5.doWithRetry(JsrFaultTolerantChunkProcessor.java:317) at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:263) at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:168) at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:222) at org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor.persist(JsrFaultTolerantChunkProcessor.java:348) at org.springframework.batch.core.jsr.step.item.JsrChunkProcessor.process(JsrChunkProcessor.java:114) at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75) at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271) at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77) at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368) at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) at org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState.handle(JsrStepState.java:53) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:165) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) at org.springframework.batch.core.jsr.job.flow.JsrFlowJob.doExecute(JsrFlowJob.java:82) at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304) at org.springframework.batch.core.jsr.launch.JsrJobOperator$2.run(JsrJobOperator.java:675) at java.lang.Thread.run(Thread.java:795) Caused by: gov.state.nextgen.framework.batch.exception.NGBatchSkipRecordException: gov.state.nextgen.in.batch.exception.INBatchException: Exception occured during processing at gov.state.nextgen.in.batch.sdx.chunk.writer.SdxRcvDlyWriter.writeItems(SdxRcvDlyWriter.java:76) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:94) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55) at java.lang.reflect.Method.invoke(Method.java:619) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) at com.sun.proxy.$Proxy18.writeItems(Unknown Source) at org.springframework.batch.jsr.item.ItemWriterAdapter.write(ItemWriterAdapter.java:55) at org.springframework.batch.core.jsr.step.item.JsrChunkProcessor.doPersist(JsrChunkProcessor.java:243) at org.springframework.batch.core.jsr.step.item.JsrFaultTolerantChunkProcessor$5.doWithRetry(JsrFaultTolerantChunkProcessor.java:298) ... 26 more Caused by: gov.state.nextgen.in.batch.exception.INBatchException: Exception occured during processing at gov.state.nextgen.in.batch.sdx.bo.impl.SdxRcvDlyBoImpl.write(SdxRcvDlyBoImpl.java:125) at gov.state.nextgen.in.batch.sdx.chunk.writer.SdxRcvDlyWriter.writeItems(SdxRcvDlyWriter.java:65) ... 41 more20 Apr 2015 18:39:14,808 DEBUG [org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:88)] - Inputs not busy, ended: false 20 Apr 2015 18:39:17,985 DEBUG [org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:437)] - Applying contribution: [StepContribution: read=2, written=0, filtered=0, readSkips=0, writeSkips=1, processSkips=0, exitStatus=EXECUTING] 20 Apr 2015 18:39:18,984 INFO [gov.state.nextgen.in.batch.sdx.chunk.writer.SdxRcvDlyWriter.checkpointInfo(SdxRcvDlyWriter.java:87)] - ParisRcvFedWriter - checkpointInfo(): step name: process, step execution id: 14939 20 Apr 2015 18:39:19,314 TRACE [org.springframework.transaction.support.TransactionSynchronizationManager.getResource(TransactionSynchronizationManager.java:140)] - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@5c4a884f] for key [org.apache.commons.dbcp.BasicDataSource@d9bdc230] bound to thread [SimpleAsyncTaskExecutor-1] 20 Apr 2015 18:39:19,314 DEBUG [org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:472)] - Participating in existing transaction 20 Apr 2015 18:39:19,314 TRACE [org.springframework.transaction.interceptor.TransactionAspectSupport.prepareTransactionInfo(TransactionAspectSupport.java:447)] - Getting transaction for [org.springframework.batch.core.repository.support.SimpleJobRepository.updateExecutionContext] 20 Apr 2015 18:39:19,315 DEBUG [org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:908)] - Executing prepared SQL update 20 Apr 2015 18:39:19,315 DEBUG [org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:627)] - Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?] I am attaching my configuration files for reference. By debugging I could find my insert statements are getting executed under transaction managed by spring and I am sure there is no issue with the transaction manager configuration