Skip to content
Advertisement

Spring Boot Batch – Stop and Start a multithreaded step with CompositeItemWriter

I am trying to stop and start a multithreaded step through Scheduler. But I am getting exception as

JavaScript

If I understand correctly we wont be able to restart an multithreaded step. But I am not restarting. I stop the job by stepExecution.setTerminateOnly() through ChunkListener() and trying to start this by jobLauncher.run() in a scheduler. Here is my codes;

JavaScript

StopListener.java This ChunkListner class implementation is used to terminate the execution any time other than between 10pm and 6am

JavaScript

And finally my scheduler method in application class. I am using CommandLneRunner to accept arguments.

JavaScript

There are some confusions. Will run method always try to restart the previous executions if it is failed? Because I could see this was still restarting and that can be the reason for this. I tried to provide new JobParameter hoping it will just launch it again. I hope my stopping method from ChunkListener is ok. But somehow I want to start this job again from Scheduler and I definitely need a multihreaded step. I also hope a CompositeWriter in a Multithreaded step is also fine. A help would be greatly appreciated. Thanks in advance!

Update : Finally I could make it work by adding reader.setVerifyCursorPosition(false). But I think I need to use thread safe Reader as suggested by Mahmoud Ben Hassine. So I am trying to use JdbcPagingItemReader but getting error as “sortKey must be specified”. I think I have specified it but not sure it is correct. Here is my JdbcPagingItemReader

JavaScript

My Updated Step

JavaScript

Advertisement

Answer

Multi-threading is not compatible with restarts. As mentioned in the Javadoc, you should set saveState to false if you use the JdbcCursorItemReader in a multi-threaded step.

Moreover, the JdbcCursorItemReader is not thread-safe as it wraps a ResultSet object which is not thread safe and also because it inherits from AbstractItemCountingItemStreamItemReader which is not thread safe neither. So using it in a multi-threaded step is incorrect. This is actually the cause of your issue Unexpected cursor position change. Concurrent threads are modifying the cursor position inadvertently.

You need to synchronize access to the reader by wrapping it in a SynchronizedIteamStreamReader or use a JdbcPagingItemReader which is thread safe.

EDIT: Add example with JdbcPagingItemReader

Here is a self-contained docker-based sample:

JavaScript

This prints items in the descending order as expected without complaining about the missing sort key:

JavaScript
Advertisement