Feb 21st, 2008, 03:46 AM
Handle exception when reading in a retry context
I want to use the stateful retry feature in a read-write tasklet, but found the following issue :
ItemReader.read() is invoked when the retry policy opens the retry context, which means outside of the retry loop. When an exception is encountered during reading, there is therefore no way to retry or recover from it : such an exception is wrapped in a ExhaustedRetryException, which is caught and rethrown by the step executor.
I understand that neither recovery path nor retry can happen properly here as no item has been read yet (needed to identify the item's retry history), but then, why not give a chance to skip it in the skip() method of the tasklet ? I see that skip() is a no-op when a retry strategy is in place in the tasklet.
I understand why skip() must do nothing in the case of a retry when the exception happens inside the retry (the item must not be skipped, as another transaction will retry it), but then, would it be possible to allow the ItemReader to skip that line in the special case when reading fails ? If ItemReader.read() fails, the transaction will rollback (resetting the reader to its initial state), and the ItemReader will try to read that same failing line, again and again. I cannot implement some kind of skip on transaction rollback, as I do not have a clue about which record actually failed (again, there is no item yet...)
A solution would be to actually implement skip() also in the context of a retry in place, but condition it to the callback state : if reading failed, invoke skip on ItemReader (if it implements Skippable), and if reading succeeded but writing failed, then do nothing.
I noticed that the chunk-oriented approach introduced in M5 drops the Skippable interface. Is this issue/use case addressed in M5 ?