This post is part of a series delving into the details of the JSR-352 (Java Batch) specification. Each post examines a very specific part of the specification and looks at how it works and how you might use it in a real batch application.To start at the beginning, follow the link to the first post.
The next post in the series is here
.This series is also available as a podcast on iTunes, Google Play, Stitcher, or use the link to the RSS feed.
The split/flow is a JSR-352 construct that allows you to run more than one step (or set of steps) concurrently within a single job. To use it you define a set of one or more steps as a flow by wrapping the step elements in begin-end flow elements. Group together the different sets of steps you want to run concurrently into separate flows. Then wrap all the flows inside begin-end split elements.
When execution hits the split element the execution of the flows inside it will spin off to different threads while the thread executing the split waits for them to complete. Once all the contained flows are complete, the split thread wakes up and continues with whatever is next in the job. You can nest a split within a flow that is within a split. There is no architected limit to the number of times you can nest or to the number of flows within a split, however practical considerations will likely impose some limit, so don’t go crazy.
For the purposes of our sample I want to focus on flow control. A split is a job element just like a step and for it to get control it either has to be the first thing in the job or control has to flow to it from some other step using normal flow control mechanisms. That means the split element needs an id attribute to give it a name.
Flows can have a name, but don’t need one when they are inside a split (wait, what? When would a flow be outside a split? Hang on…we’ll get there). Once a flow gets control inside a split, it works like a little job with the first step inside the flow getting control first and proceeding, just like a job, until no flow control directs it to a next step. You can’t have a step within a flow direct control to pass to a step outside the flow.
When all the flows have run out of steps to execute (no ‘next’ steps) then control returns to the split which goes to whatever step you’ve indicated should be next. Like everything else, if there is no next step after the split, that’s the end of the job.
Finally, what’s this about a flow that isn’t in a split? That’s perfectly legal. You can wrap a set of steps inside begin-end flow elements if you want to. In that case you’d want the flow element to have an id so that some step in the job could indicate the flow is the next thing to process. When that happens the steps inside the flow process just like they would inside a split, starting with the first one and proceeding until there is no next step indicated. Then the flow ends and control proceeds wherever indicated as the next step after the flow. Even here you can’t branch out of the flow. Independent flows like this are handy if you just want to group a set of steps together because they are part of some process. It is almost a sort of procedure, except you can’t call it more than once within the job.
Our example, UsingSplitFlow.xml, begins with a batchlet followed by a split with two flows. Each flow has two steps. When the split is done we proceed to another batchlet step, followed by an independent flow with two steps inside. Look closely at where and how next steps are indicated.
The sample parts are here: https://github.com/follisd/batch-samples