Kohei Nozaki's blog 

Chunk方式のStepで例外発生時にリトライさせてからスキップさせてみる


Posted on Monday Feb 10, 2014 at 06:57PM in Technology


Chunk方式のStepで例外発生時にスキップさせてみる でリトライとスキップをそれぞれ別々に試してみたが、ここではリトライを試み、それでも成功しない場合は、そのデータをスキップして処理を継続させる、というのをやってみる

環境・前提条件

JSR352仕様を確認する

[1]に以下のようにある

8.2.1.4.3 Retry and Skip the Same Exception

When the same exception is specified as both retryable and skippable, retryable takes precedence over skippable during regular processing of the chunk. While the chunk is retrying, skippable takes precedence over retryable since the exception is already being retried.

This allows an exception to initially be retried for the entire chunk and then skipped if it recurs. When retrying with default retry behavior (see section 8.2.1.4.4) the skips can occur for individual items, since the retry is done with an item-count of 1.

リトライの回数は1回で固定になるようだ。失敗後は1回はリトライするが、それでも駄目ならスキップとなる。retry-limitを指定してみたが、ここでリトライ回数を指定するために使われる値ではないようだ。

バッチを作る

仕様

  • 入力、出力、処理内容は基本的にChunk方式のStepで例外発生時にスキップさせてみるでやったのと同じ
  • 6件目のデータ処理時にItemReaderでRuntimeExceptionが起こる。リトライが試みられたあとさらに例外が起こり、スキップされる
    • RuntimeExceptionは以下の両方に設定してある
      • skippable-exception-classes
      • retryable-exception-classes

資源

資源はこのへんにまとめて全部ある

動かしてみる

ログ

16:36:59,072 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) open(): checkpoint=null, index starts at=0
16:36:59,076 DEBUG [org.hibernate.SQL] (batch-batch - 5) select chunkinput0_.id as id1_0_, chunkinput0_.input as input2_0_, chunkinput0_.processed as processe3_0_ from ChunkInputItem chunkinput0_ order by chunkinput0_.id
16:36:59,078 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) open(): checkpoint=null, index starts at=0
16:36:59,079 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=0, failAt=5
16:36:59,079 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=0, input=0, processed=false]
16:36:59,079 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=0, input=0, processed=false], output=ChunkOutputItem [id=0, result=0]
16:36:59,079 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=1
16:36:59,079 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=1, failAt=5
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=1, input=10, processed=false]
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=1, input=10, processed=false], output=ChunkOutputItem [id=1, result=5]
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=2
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=2, failAt=5
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=2, input=20, processed=false]
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=2, input=20, processed=false], output=ChunkOutputItem [id=2, result=10]
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=3
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): index=0
16:36:59,080 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=0, result=0]
16:36:59,081 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=1, result=5]
16:36:59,081 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=2, result=10]
16:36:59,081 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=3
16:36:59,081 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) checkpointInfo(): returns=1
16:36:59,083 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=3
16:36:59,086 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,087 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,088 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,116 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=3, failAt=5
16:36:59,117 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=3, input=30, processed=false]
16:36:59,117 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=3, input=30, processed=false], output=ChunkOutputItem [id=3, result=15]
16:36:59,117 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=4
16:36:59,117 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=4, failAt=5
16:36:59,117 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=4, input=40, processed=false]
16:36:59,117 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=4, input=40, processed=false], output=ChunkOutputItem [id=4, result=20]
16:36:59,117 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=5
16:36:59,118 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=5, failAt=5
16:36:59,118 WARNING [org.nailedtothex.jbatch.example.chunkretry.MyRetryReadListener] (batch-batch - 5) onRetryReadException(): java.lang.RuntimeException: 5
    at org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader.readItem(ChunkRetrySkipItemReader.java:43) [classes:]
    at org.jberet.runtime.runner.ChunkRunner.readItem(ChunkRunner.java:343) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.ChunkRunner.readProcessWriteItems(ChunkRunner.java:288) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.ChunkRunner.run(ChunkRunner.java:190) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.StepExecutionRunner.runBatchletOrChunk(StepExecutionRunner.java:204) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.StepExecutionRunner.run(StepExecutionRunner.java:131) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.CompositeExecutionRunner.runStep(CompositeExecutionRunner.java:162) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.CompositeExecutionRunner.runFromHeadOrRestartPoint(CompositeExecutionRunner.java:88) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.JobExecutionRunner.run(JobExecutionRunner.java:58) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.wildfly.jberet.services.BatchEnvironmentService$WildFlyBatchEnvironment$1.run(BatchEnvironmentService.java:149) [wildfly-jberet-8.0.0.Final.jar:8.0.0.Final]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0_51]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_51]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51]
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51]
    at org.jboss.threads.JBossThread.run(JBossThread.java:122)

16:36:59,119 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=6
16:36:59,119 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) close()
16:36:59,119 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) close()
16:36:59,119 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) open(): checkpoint=3, index starts at=3
16:36:59,120 DEBUG [org.hibernate.SQL] (batch-batch - 5) select chunkinput0_.id as id1_0_, chunkinput0_.input as input2_0_, chunkinput0_.processed as processe3_0_ from ChunkInputItem chunkinput0_ order by chunkinput0_.id
16:36:59,122 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) open(): checkpoint=1, index starts at=1
16:36:59,122 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=3
16:36:59,122 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=3, failAt=5
16:36:59,123 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=3, input=30, processed=false]
16:36:59,123 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=3, input=30, processed=false], output=ChunkOutputItem [id=3, result=15]
16:36:59,123 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=4
16:36:59,123 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): index=1
16:36:59,123 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=3, result=15]
16:36:59,123 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=4
16:36:59,123 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) checkpointInfo(): returns=2
16:36:59,125 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=4
16:36:59,125 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,152 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=4, failAt=5
16:36:59,152 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=4, input=40, processed=false]
16:36:59,152 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=4, input=40, processed=false], output=ChunkOutputItem [id=4, result=20]
16:36:59,153 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=5
16:36:59,153 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): index=2
16:36:59,153 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=4, result=20]
16:36:59,153 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=5
16:36:59,153 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) checkpointInfo(): returns=3
16:36:59,155 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=5
16:36:59,155 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,183 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=5, failAt=5
16:36:59,183 WARNING [org.nailedtothex.jbatch.example.chunkskip.MySkipReadListener] (batch-batch - 5) onSkipReadItem(): java.lang.RuntimeException: 5
    at org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader.readItem(ChunkRetrySkipItemReader.java:43) [classes:]
    at org.jberet.runtime.runner.ChunkRunner.readItem(ChunkRunner.java:343) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.ChunkRunner.readProcessWriteItems(ChunkRunner.java:288) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.ChunkRunner.run(ChunkRunner.java:190) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.StepExecutionRunner.runBatchletOrChunk(StepExecutionRunner.java:204) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.StepExecutionRunner.run(StepExecutionRunner.java:131) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.CompositeExecutionRunner.runStep(CompositeExecutionRunner.java:162) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.CompositeExecutionRunner.runFromHeadOrRestartPoint(CompositeExecutionRunner.java:88) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.jberet.runtime.runner.JobExecutionRunner.run(JobExecutionRunner.java:58) [jberet-core-1.0.1.Beta-SNAPSHOT.jar:1.0.1.Beta-SNAPSHOT]
    at org.wildfly.jberet.services.BatchEnvironmentService$WildFlyBatchEnvironment$1.run(BatchEnvironmentService.java:149) [wildfly-jberet-8.0.0.Final.jar:8.0.0.Final]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0_51]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_51]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51]
    at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51]
    at org.jboss.threads.JBossThread.run(JBossThread.java:122)

16:36:59,185 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=6
16:36:59,185 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=6, failAt=5
16:36:59,186 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=6, input=60, processed=false]
16:36:59,186 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=6, input=60, processed=false], output=ChunkOutputItem [id=6, result=30]
16:36:59,186 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=7
16:36:59,186 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=7, failAt=5
16:36:59,187 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=7, input=70, processed=false]
16:36:59,187 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=7, input=70, processed=false], output=ChunkOutputItem [id=7, result=35]
16:36:59,187 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=8
16:36:59,187 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=8, failAt=5
16:36:59,187 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=8, input=80, processed=false]
16:36:59,187 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=8, input=80, processed=false], output=ChunkOutputItem [id=8, result=40]
16:36:59,187 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=9
16:36:59,188 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): index=3
16:36:59,188 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=6, result=30]
16:36:59,188 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=7, result=35]
16:36:59,189 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=8, result=40]
16:36:59,189 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=9
16:36:59,189 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) checkpointInfo(): returns=4
16:36:59,191 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=9
16:36:59,191 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,192 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,193 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,221 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=9, failAt=5
16:36:59,221 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=ChunkInputItem [id=9, input=90, processed=false]
16:36:59,221 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemProcessor] (batch-batch - 5) processItem(): input=ChunkInputItem [id=9, input=90, processed=false], output=ChunkOutputItem [id=9, result=45]
16:36:59,221 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=10
16:36:59,221 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): index=10, failAt=5
16:36:59,221 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) readItem(): returning=null
16:36:59,221 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): index=4
16:36:59,222 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) writeItems(): item=ChunkOutputItem [id=9, result=45]
16:36:59,222 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=10
16:36:59,222 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) checkpointInfo(): returns=5
16:36:59,223 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) checkpointInfo(): returns=10
16:36:59,224 DEBUG [org.hibernate.SQL] (batch-batch - 5) insert into ChunkOutputItem (result, id) values (?, ?)
16:36:59,252 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) close()
16:36:59,269 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) close()
16:36:59,270 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemReader] (batch-batch - 5) close()
16:36:59,270 FINE  [org.nailedtothex.jbatch.example.chunkretryskip.ChunkRetrySkipItemWriter] (batch-batch - 5) close()

Repository

job_execution

jbatch=# select * from job_execution order by jobexecutionid desc limit 1;
 jobexecutionid | jobinstanceid | version |       createtime        |        starttime        |         endtime         |     lastupdatedtime     | batchstatus | exitstatus |    jobparameters     | restartposition 
----------------+---------------+---------+-------------------------+-------------------------+-------------------------+-------------------------+-------------+------------+----------------------+-----------------
            127 |           122 |         | 2014-02-15 16:36:59.068 | 2014-02-15 16:36:59.068 | 2014-02-15 16:36:59.272 | 2014-02-15 16:36:59.272 | COMPLETED   | COMPLETED  | itemReaderFailAt = 5+| 
                |               |         |                         |                         |                         |                         |             |            | divide = 2          +| 
                |               |         |                         |                         |                         |                         |             |            |                      | 
(1 row)

step_execution

jbatch=# select * from step_execution where jobexecutionid =127;
 stepexecutionid | jobexecutionid | version | stepname |       starttime        |        endtime         | batchstatus | exitstatus | executionexception | persistentuserdata | readcount | writecount | commitcount | rollbackcount | readskipcount | processskipcount | filtercount | writeskipcount |                                                                         readercheckpointinfo                                                                         |                                                                         writercheckpointinfo                                                                         
-----------------+----------------+---------+----------+------------------------+------------------------+-------------+------------+--------------------+--------------------+-----------+------------+-------------+---------------+---------------+------------------+-------------+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------
             142 |            127 |         | doChunk  | 2014-02-15 16:36:59.07 | 2014-02-15 16:36:59.27 | COMPLETED   | COMPLETED  |                    |                    |        11 |          9 |           5 |             1 |             1 |                0 |           0 |              0 | \xaced0005737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b02000078700000000a | \xaced0005737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000005
(1 row)

動作の流れを見てみる

ざっくり

  1. 3件目までは普通に完走
  2. 6件目で例外が起きて、バッファリングされていた4, 5件目の処理結果は破棄
  3. item-count=1に設定されリトライが行われる
  4. 4, 5件目が1件ずつ処理されて結果がDBに書き込まれる
  5. 6件目で2回目の例外が起きる。6件目はあきらめてスキップされる
  6. 7件目以降が1件ずつ処理されて完走

備考

  • リトライの回数を指定できると嬉しいような気はするがまあこれはこれでいいのかも
  • アプリ側でリトライの回数を数えて、あきらめる時はスキップ用例外を投げる、みたいな感じで制御してもいいかも

参考文献

  1. JSR-000352 Batch Applications for the Java Platform - Final Release



No one has commented yet.

Leave a Comment

HTML Syntax: NOT allowed