Search code examples
javaspringwebsphere

How to execute a particular method in java before websphere goes down?


I have a job in java application which is reading data from Oracle database using spring JDBC after every 5 mins. The java application is running on WebSphere Application Server. It loads records with status 'X', after loading records it changes status of records to 'Y'. We are reading 10k records at a time and supplying 1k records to each thread within 10 threads for certain Processing.

After processing each record, the record state gets changed to 'Z'. Now if something goes wrong while processing records like outOfMemory error and WebSphere goes down, the record state remains 'Y'.

So when next time Server starts, the job starts reading records with status 'X'. But the records which are unprocessed with status 'Y' will never get loaded now. So is there any way to call a method while WebSphere goes down? Within which i can write a piece of code to make the status of unprocessed records to 'X', so that they can get picked next time server starts.


Solution

  • If the application has encountered an OutOfMemoryError there is really no reliable way for you to make sure that some code gets executed before going down (actually, the OutOfMemoryError will not actually make the process die by itself, but it doesn't matter - if you're out of memory you can't be sure that you will be able to do anything at all in that process).

    What you should to do is get rid of the 'Y' state. Just make sure that the job that reads the items doesn't get to execute more than once (see below). You should then be able to just read the items, send them off for processing, and just set the state to 'Z' when you're done (preferably in the same transaction as the processing of each item).

    Now, you don't specify how your job is kicked off every five minutes, so I'm just assuming you're using Spring's scheduling functionality for that. If this is the case, the job will never get fired more than once as long as it's still running. This means that your job needs to keep track of the items it's sent off and wait for them to finish before exiting. This can be done using an ExecutorCompletionService. Send each subtask (i.e. chunk of 1k records) to the same ExecutorCompletionService and poll for finished tasks as long as there are more tasks left. When all subtasks have returned you can safely exit the parent job.

    Another way of doing this (if the 'Y' state is required for some particular reason) would be to check for 'Y' records on startup, e.g. in a method annotated with @PostConstruct