Where does Spring Batch saves the batch execution state? - spring

I have a spring batch job that takes a long time to execute. After executing for a while I decided I wanted to stop it but whenever I restart the server the job still continues executing after the server come back up.
I want to know where spring batch saves the state so that I can possibly delete it and stop that from happening.
I found out there are properties that I can configure to not have the job restartable and I will use that going forward but now I just need to make sure the job can stop for good.

You can see the documentation here which shows & describes the spring Batch Meta-Data tables.

if you just want to prevent restart of job below config should help you.
preventRestart() helps to avoid restart of job
https://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/job/builder/JobBuilderHelper.html
#Bean
public Job myJob(JobBuilderFactory jobs) throws Exception {
return jobs.get("myJob")
.flow(step1())
.build()
.preventRestart()
.build();
}

Related

Need some guidance with Spring Integration Flow

I am new to Spring Integration and have read quite some documentation and other topics here on StackOverflow. But I am still a bit overwhelmed on how to apply the newly acquired knowledge in a Spring Boot Application.
This is what should happen:
receive message from a Kafka topic, eg from "request-topic" (payload is a custom Job POJO). InboundChannelAdapter?
do some preparation (checkout from a git repo)
process files using a batch job
commit&push to git, update Job object with commit-id
publish message to Kafka with updated Job object, eg to "reply-topic". OutboundChannelAdapter?
Using DSL or plain Java configuration does not matter. My problem after trying several variants is that I could not achieve the desired result. For example, handlers would be called too early, or not at all, and thus the reply in step 5 would not be updated.
Also, there should only be one flow running at any given time, so I guess, a queue should be involved at some point, probably at step 1(?).
Where and when should I use QueueChannels, DirectChannel (or any other?), do I need GatewayHandlers, eg to reply with a commit-id?
Any hints are appreciated.
Something like this:
#Bean
IntegrationFlow flow() {
return IntegrationFlows.from(Kafka.inboundGateway(...))
.handle(// prep)
.transform(// to JobLaunchRequest)
.handle(// JobLaunchingGateway)
.handle(// cleanUp and return result)
.get();
}
It will only process one request at a time (with default concurrency).

Spring Batch: Implementing stop method in StoppableTasklets

I am calling the following piece to stop the job.
Set<Long> executions = jobOperator.getRunningExecutions("Job-Builder");
jobOperator.stop(longExecutions.iterator().next());
The above method is stopping the job but Tasklets are still running. After reading through comments from stackoverflow I changed tasklet to use StoppableTasklet in my project so that I can stop them from running when I call the joboperator.stop()
My question here is that I am not sure how to identify if a job has been stopped and do necessary action inside the stop overriden method when I implement StoppableTasklet. Can you tell me on how I can do that in the overridden method?
My question here is that I am not sure how to identify if a job has been stopped and do necessary action inside the stop overriden method when I implement StoppableTasklet
You don't need to identify if the job has been stopped in your code. You need to implement the logic to stop the current tasklet and this logic will be called by the framework when you stop the job through JobOperator#stop.

Trigger spring batch job automatically

Is there any option to run Spring Batch job automatically without scheduling or trigger it from other source?
We can run spring batch job by scheduling expression or by main method (As mentioned below).
public static void runBatch() {
JobLauncher jobLauncher = (JobLauncher) getApplicationContext().getBean("jobLauncher");
Job job = get Job details here;
JobParametersBuilder jobParameters = new JobParametersBuilder();
// Setting Job Parameter and run job using below
JobExecution jobExecution = jobLauncher.run(job, jobParameters.toJobParameters());
}
public static void main(String[] args) {
runBatch();
}
Means we need to call main method manually or by some other scheduler so that it will trigger. Without this main method or scheduler can we call this batch process automatically? Or Is there any better options?
Spring batch should trigger automatically without triggering from any entry point its like daemon thread.
Suppose once batch is processing data using spring batch. How can automatically trigger spring batch job after completion of running
job?
Many options exist to trigger the batch:
To call a batch from another scheduler, issue run parameters there and trigger the Job.
If it has to be triggered automatically, say may be on certain interval, use fixedDelay scheduling
To trigger manually, you can go for MBean approach where it can be triggered from JConsole.
Or have an endpoint to call runBatch.

Spring Batch Process Questions

2 questions on spring batch , Can someone please shed more light on this.
1) I have implemented registerShutdownHook in my spring batch project, but when I do kill my batch process it is not stopping immediately. It is waiting till the entire batch process is completed. Thats how it works?
public static void main(String[] args) {
final AbstractApplicationContext appContext = new AnnotationConfigApplicationContext("\"com.lexisnexis.batch\",\"com.lexisnexis.rules\"");
appContext.registerShutdownHook();
...
}
Does it needs to stop all running batches and when we do kill with this registerShutdownHook code?
2) What is the best way to restart all stopped jobs?
Yes, that's how it works. It's needed to close spring application context gracefully. Please check spring framework's documentation.
To restart your stopped job you need to invoke jobOperator.restart(executionId) or use jobLauncher.run with same parameters you used to start original job.

using Spring integration with spring batch

I have a spring batch application which reads from file , does some processing and finally write a customized output. This all happens in one step. In next step i have a tasklet which archives the input files (move to another folder). This application works fine.But, now i got a requirement to sftp output files on a remote servers where they would further processed. I got a way to sftp using spring integration where i have created a input channel which feeds to outboundchannel adapter. I put my files as payload in message and send messages to channel. The only problem i see here is that everytime I have to get the context i eed to load the spring config file, which seems kind of hackish way to do the task. Does anyone know about any way to integrate SI with SB.
Let me know if you want to see my config...
Thanks in Advance !!
code to access the same app-context without loading the spring config again
public class AppContextProvider implements ApplicationContextAware{
private static ApplicationContext ctx;
public ApplicationContext getApplicationContext() {
return ctx;
}
public void setApplicationContext(ApplicationContext appContext) throws BeansException {
ctx = appContext;
}
}
code to push the output file to sftp server
log.info("Starting transfer of outputFile : " + absoluteOutputFileName);
final File file = new File(absoluteOutputFileName);
final Message<File> message = MessageBuilder.withPayload(file).build();
AppContextProvider context = new AppContextProvider();
final MessageChannel inputChannel = context.getApplicationContext().getBean("toChannel",MessageChannel.class);
inputChannel.send(message);
log.info("transfer complete for : " + absoluteOutputFileName);
Take a look at the spring-batch-integration module within the Spring Batch project. In there, we have components for launching jobs via messages. In your situation, you'd FTP the file down then have the JobLaunchingMessageHandler launch the job.
You can also watch this video of a talk I co-presented at SpringOne a couple years ago on this topic: https://www.youtube.com/watch?v=8tiqeV07XlI
As Michael said, you'll definitely want to look at and leverage spring-batch-integration. We actually use Spring Integration as a wrapper of sorts to launch 100% of our Spring Batch jobs.
One use case we've found particularly useful is leveraging the spring-integration-file Inbound Channel Adapters to poll staging directories to indicate when a new batch file has landed. As the poller finds a new file, we then launch a new batch job using the input filename as a parameter.
This has been a real help when it comes to restartability, because we now have one job instance per file as opposed to having a job kick off at arbitrary intervals and then partition across however many files happen to be in the staging folder. Now if an exception occurs during processing, you can target a specific job for restart immediately rather than waiting for 99 of the 100 "good" files to finish first.

Resources