This post is part of a series delving into the details of the JSR-352 (Java Batch) specification. Each post examines a very specific part of the specification and looks at how it works and how you might use it in a real batch application.To start at the beginning, follow the link to the first post.
The next post in the series is here
.This series is also available as a podcast on iTunes, Google Play, Stitcher, or use the link to the RSS feed.
I was recently reminded of a rather specific paragraph in section 220.127.116.11.3 of the JSR-352 specification. I’ve quoted it here:
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.
What does that mean? Let’s consider an example. Suppose your job is processing records with nice integer record numbers. We’re working with an item-count of 10 to keep things simple. The job reads and processes records 1-10 without a problem. The writer is called with the processing results, and checkpoint processing completes.
Then we start the second chunk with record 11. All goes well until we begin processing record number 13 (because it is unlucky). An exception is thrown by the processor which is listed in the JSL as both a skippable and retryable (with rollback) exception. What happens next?
The current transaction is rolled back (undoing anything done by the reader or processor handling things since the commit of the first chunk). The reader and writer are closed and re-opened with the checkpoint data from the previous chunk. We begin again at record 11. Since we are in retry processing the item count changes temporarily to one. That causes the step to read/process/write for record 11 and commit the one-record chunk. This happens again for record 12.
Unlucky record 13 again has a problem and throws the same exception. This time we’re in retry processing so the special rule above applies. The exception is handled as a skippable exception and we skip the record. The chunk will complete and retry processing ends (because this is the record that caused the retry-rollback processing to start).
After that we’re back to regular 10-item chunk processing starting with record 14.
So what? Well, specifying an exception as both skippable and retryable allows you to rollback and redo processing for records up to the problem one, but then continue on skipping the problem record if a retry at handling it fails again.
Without the skippable specification for the exception retry processing would kick in again and we’d make another try at record 13. If it continues to fail, we’ll just keep retrying until we hit the retry limit for the step and the step fails. That assumes you specified one…you did remember to specify a retry limit when you set up retry processing, didn’t you? The default is no-limit which is probably not what you wanted.