[[controllingRollback]]
= Controlling Rollback

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, you can configure the `Step` with a list of exceptions that should not
cause rollback.

[tabs]
====
Java::
+
In Java, you can control rollback as follows:
+
.Java Configuration
[source, java]
----
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
	return new StepBuilder("step1", jobRepository)
				.<String, String>chunk(2, transactionManager)
				.reader(itemReader())
				.writer(itemWriter())
				.faultTolerant()
				.noRollback(ValidationException.class)
				.build();
}
----

XML::
+
In XML, you can control rollback as follows:
+
.XML Configuration
[source, xml]
----
<step id="step1">
   <tasklet>
      <chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>
      <no-rollback-exception-classes>
         <include class="org.springframework.batch.item.validator.ValidationException"/>
      </no-rollback-exception-classes>
   </tasklet>
</step>
----

====



[[transactionalReaders]]
== Transactional Readers

The basic contract of the `ItemReader` is that it is forward-only. The step buffers
reader input so that, in case of a rollback, the items do not need to be re-read
from the reader. However, there are certain scenarios in which the reader is built on
top of a transactional resource, such as a JMS queue. In this case, since the queue is
tied to the transaction that is rolled back, the messages that have been pulled from the
queue are put back on. For this reason, you can configure the step to not buffer the
items.


[tabs]
====
Java::
+
The following example shows how to create a reader that does not buffer items in Java:
+
.Java Configuration
[source, java]
----
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
	return new StepBuilder("step1", jobRepository)
				.<String, String>chunk(2, transactionManager)
				.reader(itemReader())
				.writer(itemWriter())
				.readerIsTransactionalQueue()
				.build();
}
----

XML::
+
The following example shows how to create a reader that does not buffer items in XML:
+
.XML Configuration
[source, xml]
----
<step id="step1">
    <tasklet>
        <chunk reader="itemReader" writer="itemWriter" commit-interval="2"
               is-reader-transactional-queue="true"/>
    </tasklet>
</step>
----

====


