Skip to content

Clarify/fix documentation of skips and controlling rollback with FaultTolerantStepBuilder #3748

Open
@goatfryed

Description

@goatfryed

I'm referring to 5.1.5. Configuring Skip Logic and 5.1.7. Controlling Rollback of the Spring batch reference documentation.

I think, the current documentation does not accurately document the current functionality and would like to help to improve on it.

In short:

  • The current documentation does not accurately describe the actual behavior
  • It contradicts the javadoc
  • It does not clearly state behavior of ItemProcessor, which creates additional confusion in combination with the above.

The documentaton states that we should use .skip(FlatFileParseException.class) to skip exceptions, that do not cause errors to the batch. I'd expect that this means that it behaves more or less like a filter with regards to processing, but it actually rolls back the current chuck and processes it one item at a time, which might be kind of unexpected, if we use non-transactional readers and processors. It's possible to find better documentation at other places, but it sounds misleading here.

Now, in 5.1.7, the documentation states

By default, regardless of retry or skip, any exceptions thrown from the ItemWriter cause the transaction controlled by the Step to rollback. If skip is configured as described earlier, exceptions thrown from the ItemReader do not cause a rollback. However, there are many scenarios in which exceptions thrown from the ItemWriter should not cause a rollback, because no action has taken place to invalidate the transaction. For this reason, the Step can be configured with a list of exceptions that should not cause rollback, as shown in the following example:

If skip is configured as described earlier
This can only refer to .skip(FlatFileParseException.class). So it reenforces the idea, that skip shouldn't cause a rollback. Also, this paragraph directly contradicts the javadocs that state, that the noRollback definition is ignored in writing.

	/**
	 * Mark this exception as ignorable during item read or processing operations. Processing continues with no
	 * additional callbacks (use skips instead if you need to be notified). Ignored during write because there is no
	 * guarantee of skip and retry without rollback.
	 *
	 * @param type the exception to mark as no rollback
	 * @return this for fluent chaining
	 */
	public FaultTolerantStepBuilder<I, O> noRollback(Class<? extends Throwable> type) { /* ... */}

So, to skip exceptions in item reader, processor and writer, but rollback the current chunk and retry one by one, we should use

stepBuilderFactory.get("...")
                .faultTolerant()
                    .skip(ValidationException.class)

To silently skip exceptions in item reader or processor, while continuing with the current chunk, we should use

stepBuilderFactory.get("...")
                .faultTolerant()
                    .noRollback(ValidationException.class)

And if we want to skip an exception in item reader or processor, but handle it in a SkipListener, we have to define

stepBuilderFactory.get("...")
                .faultTolerant()
                    .skip(ValidationException.class)
                    .noRollback(ValidationException.class)

But we should take extra care, because this would also skip the same exception in a writer, together with a rollback.

If you agree with me that the documentation might benefit from a bit clarification and improvement here and I haven't stated anything wrong, I'd be happy to propose an update here

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions