我正在尝试调查在编写器中抛出异常时会发生什么。根据理论,我期望发生回滚,然后重试块设置提交大小为 1。但这没有发生,我收到以下错误。
我正在使用 Spring Batch -JSR 352 作业设计。在作者中,我有 3 个 JDBC 调用。如果我在成功执行 2 个 JDBC 调用后抛出一个可跳过的异常,那么我会发现 Spring 批处理无法回滚该块的事务并通过将提交大小设置为 1 来重试该块。我收到以下执行,之后整个块被跳过并且我们正在进行块提交。结果,已经写入 2 个 JDBC 表的数据被持久化,缺少第 3 个表数据。
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 = ?]
我附上我的配置文件以供参考。通过调试,我可以发现我的插入语句正在由 spring 管理的事务下执行,我确信事务管理器配置没有问题