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.
Well, that’s a bit dark. What we’re talking about this time is the split feature of JSR-352. Splits give us the ability to run multiple steps concurrently within the same job. Generally we think of a job as a list of steps that run in some sequence. But there might be times where you have two steps that really don’t depend on one another. Step A can run before or after Step B, but both have to run before Step C. Wouldn’t it be cool if you could run Steps A and B concurrently?
To define a split, you first have to group the steps that need to run together into flows. In our example that would just be two flows, one with Step A and another with Step B. But the flows could easily be more complicated and consist of a group of steps, some conditional flows, maybe even a nested split within a flow.
Once you have the flows defined in the JSL, one after the other, you simply wrap them in a begin/end split element and there you go. The split element will have an id and be the target of some flow control from elsewhere in the job. When execution reaches the split, the main job thread will pause, and work will be spun off to other threads to try to run the flows within the split concurrently. I say ‘try’ because of course there is no guarantee the system will actually be able to run them concurrently, but it might.
We’ve talked about some of the issues of multi-threading before, but let’s revisit them here. First of all, each of these threads gets a separate instance of the JobContext. This gives you access to the Job Properties that are common across the job. However, remember that each thread has its own Transient User Data. You can use that to share data across steps within a flow, but not across the flows. Also remember that branches between steps in a flow have to stay within the flow.
Another consequence of having a separate JobContext is the inability to set the Job’s Exit Status. The Exit Status for the job is controlled from the Job Context on the main job thread. Don’t bother setting it within a flow in a split. Similarly having flow control elements that fail or stop the job are not advisable within flows in a split.
When all the flows within a split are finished, execution proceeds to the job element identified on the next attribute of the split. You might want that to be a Decision element. We’ll talk about those next time.