Files
spring-batch/build/reference-epub-work/ch11s02.xhtml
Michael Minella 75ab909314 update
2017-03-23 10:18:33 -05:00

90 lines
4.5 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:pls="http://www.w3.org/2005/01/pronunciation-lexicon" xmlns:ssml="http://www.w3.org/2001/10/synthesis" xmlns:svg="http://www.w3.org/2000/svg"><head><title>Stopping a Job Manually for Business Reasons</title><link rel="stylesheet" type="text/css" href="docbook-epub.css"/><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"/><link rel="prev" href="ch11.xhtml" title="Chapter 11. Common Batch Patterns"/><link rel="next" href="ch11s03.xhtml" title="Adding a Footer Record"/></head><body><header/><section class="section" title="Stopping a Job Manually for Business Reasons" epub:type="subchapter" id="stoppingAJobManuallyForBusinessReasons"><div class="titlepage"><div><div><h2 class="title" style="clear: both">Stopping a Job Manually for Business Reasons</h2></div></div></div>
<p>Spring Batch provides a <code class="methodname">stop</code>() method
through the <code class="classname">JobLauncher</code> interface, but this is
really for use by the operator rather than the application programmer.
Sometimes it is more convenient or makes more sense to stop a job
execution from within the business logic.</p>
<p>The simplest thing to do is to throw a
<code class="classname">RuntimeException</code> (one that isn't retried
indefinitely or skipped). For example, a custom exception type could be
used, as in the example below:</p>
<pre class="programlisting">public class PoisonPillItemWriter implements ItemWriter&lt;T&gt; {
public void write(T item) throws Exception {
if (isPoisonPill(item)) {
throw new PoisonPillException("Posion pill detected: " + item);
}
}
}</pre>
<p>Another simple way to stop a step from executing is to simply return
<code class="code">null</code> from the <code class="classname">ItemReader</code>:</p>
<pre class="programlisting">public class EarlyCompletionItemReader implements ItemReader&lt;T&gt; {
private ItemReader&lt;T&gt; delegate;
public void setDelegate(ItemReader&lt;T&gt; delegate) { ... }
public T read() throws Exception {
T item = delegate.read();
if (isEndItem(item)) {
return null; // end the step here
}
return item;
}
}</pre>
<p>The previous example actually relies on the fact that there is a
default implementation of the <code class="classname">CompletionPolicy</code>
strategy which signals a complete batch when the item to be processed is
null. A more sophisticated completion policy could be implemented and
injected into the <code class="classname">Step</code> through the
<code class="classname">SimpleStepFactoryBean</code>:</p>
<pre class="programlisting">&lt;step id="simpleStep"&gt;
&lt;tasklet&gt;
&lt;chunk reader="reader" writer="writer" commit-interval="10"
<span class="bold"><strong>chunk-completion-policy="completionPolicy"</strong></span>/&gt;
&lt;/tasklet&gt;
&lt;/step&gt;
&lt;bean id="completionPolicy" class="org.example...SpecialCompletionPolicy"/&gt;</pre>
<p>An alternative is to set a flag in the
<code class="classname">StepExecution</code>, which is checked by the
<code class="classname">Step</code> implementations in the framework in between
item processing. To implement this alternative, we need access to the
current <code class="classname">StepExecution</code>, and this can be achieved by
implementing a <code class="classname">StepListener</code> and registering it with
the <code class="classname">Step</code>. Here is an example of a listener that
sets the flag:</p>
<pre class="programlisting">public class CustomItemWriter extends ItemListenerSupport implements StepListener {
private StepExecution stepExecution;
public void beforeStep(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
public void afterRead(Object item) {
if (isPoisonPill(item)) {
stepExecution.setTerminateOnly(true);
}
}
}</pre>
<p>The default behavior here when the flag is set is for the step to
throw a <code class="classname">JobInterruptedException</code>. This can be
controlled through the <code class="classname">StepInterruptionPolicy</code>, but
the only choice is to throw or not throw an exception, so this is always
an abnormal ending to a job.</p>
</section><footer/></body></html>