BATCH-691:Cleaned up chapter 4. Corrected the modifications made around transaction configuration in the repository and step implementations. Also added a small section about the SystemCommandTasklet.
This commit is contained in:
@@ -499,16 +499,13 @@
|
||||
<section>
|
||||
<title>Transaction Configuration For the JobRepository</title>
|
||||
|
||||
<para>If the JDBC daos are used with the JobRepository it is also
|
||||
essential to configure the transactional behaviour of the
|
||||
<para>If either of the JobRepository factory beans are used,
|
||||
transactional advice will be automatically created around the
|
||||
repository. This is to ensure that the batch meta data, including
|
||||
state that is necessary for restarts after a failure, is persisted
|
||||
correctly. The behaviour of the framework is not well defined if the
|
||||
repository methods are not transactional. If you use the
|
||||
<classname>JobRepositoryFactoryBean</classname> then the transaction
|
||||
manager will be set up for you (this was not the case with Spring
|
||||
Batch version 1.0.x). The isolation level in the
|
||||
<code>create*</code> method attiributes is specified separately to
|
||||
repository methods are not transactional. The isolation level in the
|
||||
<code>create*</code> method attributes is specified separately to
|
||||
ensure that when jobs are launched there if two processes are trying
|
||||
to launch the same job at the same time, only one will succeed. The
|
||||
default isolation level for that method is SERIALIZABLE, which is
|
||||
@@ -517,23 +514,35 @@
|
||||
collide in this way. However, since a call to the
|
||||
<classname>create*</classname> method is quite short, it is unlikely
|
||||
that the SERIALIZED will cause problems, as long as the database
|
||||
platform supports it.</para>
|
||||
platform supports it. However, this can be overriden in the factory
|
||||
beans:</para>
|
||||
|
||||
<para>To use the map DAOs you should add transaction boundaries
|
||||
declaratively to the repository. Here is the relevant
|
||||
configuration:</para>
|
||||
<para><programlisting> <bean id="jobRepository"
|
||||
class="org.springframework.batch.execution.repository.JobRepositoryFactoryBean"
|
||||
<property name="databaseType" value="hsql" />
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="transactionManager" ref="transactionManager" />
|
||||
<emphasis role="bold"><property name="IsolationLevelForCreate" value="ISOLATION_REPEATABLE_READ" /></emphasis>
|
||||
</bean></programlisting></para>
|
||||
|
||||
<para><programlisting><aop:config>
|
||||
<aop:advisor
|
||||
pointcut="execution(* org.springframework.batch.core..*Repository+.*(..))"
|
||||
<advice-ref="txAdvice" />
|
||||
</aop:config>
|
||||
<para>If the factory beans aren't used then it is also essential to
|
||||
configure the transactional behaviour of the repository using
|
||||
AOP:</para>
|
||||
|
||||
<tx:advice id="txAdvice" transaction-manager="transactionManager">
|
||||
<tx:attributes>
|
||||
<tx:method name="*" />
|
||||
</tx:attributes>
|
||||
</tx:advice></programlisting></para>
|
||||
<para><programlisting>
|
||||
<aop:config>
|
||||
<aop:advisor
|
||||
pointcut="execution(* org.springframework.batch.core..*Repository+.*(..))"
|
||||
<advice-ref="txAdvice" />
|
||||
</aop:config>
|
||||
|
||||
<tx:advice id="txAdvice" transaction-manager="transactionManager">
|
||||
<tx:attributes>
|
||||
<tx:method name="*" />
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
</programlisting></para>
|
||||
|
||||
<para>This fragment can be used as is, with almost no changes.
|
||||
Remember also to include the appropiate namespace declarations and
|
||||
@@ -586,9 +595,9 @@
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>BATCH_STEP_EXECUTION_CONTEXT</entry>
|
||||
<entry>BATCH_EXECUTION_CONTEXT</entry>
|
||||
|
||||
<entry>STEP_EXECUTION_ID = ? and KEY_NAME = ?</entry>
|
||||
<entry>EXECUTION_ID = ? and KEY_NAME = ?</entry>
|
||||
|
||||
<entry>On commit interval, a.k.a. chunk</entry>
|
||||
</row>
|
||||
@@ -620,11 +629,11 @@
|
||||
<title>SimpleJob</title>
|
||||
|
||||
<para>The only current implementation of the <classname>Job</classname>
|
||||
interface is <classname>SimpleJob</classname>. Since a Job is just a
|
||||
simple loop through a list of Steps, this implementation should be
|
||||
sufficient for the majority of needs. It has only three required
|
||||
dependencies: a name, <classname>JobRepository</classname>, and a list
|
||||
of Steps.</para>
|
||||
interface is <classname>SimpleJob</classname>. Since a
|
||||
<classname>Job</classname> is just a simple loop through a list of
|
||||
Steps, this implementation should be sufficient for the majority of
|
||||
needs. It has only three required dependencies: a name,
|
||||
<classname>JobRepository</classname>, and a list of Steps.</para>
|
||||
|
||||
<programlisting> <bean id="footballJob"
|
||||
class="org.springframework.batch.core.job.SimpleJob">
|
||||
@@ -654,8 +663,9 @@
|
||||
role="bold">It is entirely up to the developer to ensure that a new
|
||||
instance is always created in this scenario</emphasis>. However,
|
||||
Spring Batch does provide some help. If a Job should never be
|
||||
restarted, but should always be run as part of a new JobInstance, then
|
||||
the restartable property may be set to 'false':</para>
|
||||
restarted, but should always be run as part of a new
|
||||
<classname>JobInstance</classname>, then the restartable property may
|
||||
be set to 'false':</para>
|
||||
|
||||
<programlisting> <bean id="footballJob"
|
||||
class="org.springframework.batch.core.job.SimpleJob">
|
||||
@@ -1142,9 +1152,9 @@
|
||||
<property name="retryableExceptionClasses" value="org.springframework.dao.DeadlockLoserDataAccessException" /></emphasis>
|
||||
</bean></programlisting>
|
||||
|
||||
<para>The StatefulRetryStepFactoryBean requires a limit for the number
|
||||
of times an individual item can be retried, and a list of Exceptions
|
||||
that are 'retryable'.</para>
|
||||
<para>The <classname>StatefulRetryStepFactoryBean</classname> requires
|
||||
a limit for the number of times an individual item can be retried, and
|
||||
a list of Exceptions that are 'retryable'.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -1158,20 +1168,27 @@
|
||||
there are many scenarios in which exceptions thrown from the
|
||||
<classname>ItemWriter</classname> should not cause a rollback because
|
||||
no action has taken place to invalidate the transaction. For this
|
||||
reason, the SkipLimitStepFactoryBean can be configured with a list of
|
||||
exceptions that should not cause rollback:</para>
|
||||
reason, the <classname>SkipLimitStepFactoryBean</classname> can be
|
||||
configured with a list of exceptions that should not cause
|
||||
rollback:</para>
|
||||
|
||||
<programlisting> <bean id="step2"
|
||||
class="org.springframework.batch.core.step.item.SkipLimitStepFactoryBean">
|
||||
<property name="commitInterval" value="2" />
|
||||
<property name="skipLimit" value="1" />
|
||||
<emphasis role="bold"><property name="noRollbackForExceptionClasses"
|
||||
value="org.springframework.batch.item.validator.ValidationException" /></emphasis>
|
||||
<!-- No rollback for exceptions that are marked with "+" in the tx attributes -->
|
||||
<emphasis role="bold"><property name="transactionAttribute"
|
||||
value="+org.springframework.batch.item.validator.ValidationException" /></emphasis>
|
||||
<property name="itemReader"
|
||||
ref="tradeSqlItemReader" />
|
||||
<property name="itemWriter"
|
||||
ref="itemTrackingWriter" />
|
||||
</bean></programlisting>
|
||||
|
||||
<para>The <classname>TransactionAttribute</classname> property above
|
||||
can be used to control multiple other settings such as isolation and
|
||||
propagation behaviour. More information on setting transaction
|
||||
attributes can be found in the spring core documentation.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -1461,6 +1478,27 @@
|
||||
<constructor-arg value="target/test-outputs/test-dir" />
|
||||
</bean></programlisting>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Executing System Commands</title>
|
||||
|
||||
<para>Many batch jobs may require that an external command be called
|
||||
from within the batch job. Such a process could be kicked off
|
||||
separately by the scheduler, but the advantage of common meta-data
|
||||
about the run would be lost. Furthermore, a multi-step job would also
|
||||
need to be split up into multiple jobs as well. Because the need is so
|
||||
common, Spring Batch provides a <classname>Tasklet</classname>
|
||||
implementation for calling system commands:</para>
|
||||
|
||||
<programlisting>
|
||||
<bean class="org.springframework.batch.sample.tasklet.SystemCommandTasklet">
|
||||
<property name="command" value="echo hello" />
|
||||
<!-- 5 second timeout for the command to complete -->
|
||||
<property name="timeout" value="5000" />
|
||||
</bean>
|
||||
|
||||
</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user