Apr 29th, 2008, 09:08 AM
Access same bean which is thread safe
This is my requirement
The first step of each job, reads the data from table and populate object. This object should be thread safe, because more than one job is running concurrently. Then the second step access that bean and continue the process. So here, I want to access the bean which is created in step 1.
I am planning to implement this requirement in following way-
Create a bean using BeanFactory,getBean() methode in first step. The remaining part of first step is setting the bean properties from database. In second step, access the same bean which is created in first step using same BeanFactory,getBean() and do the remaining stuff.
In above methode, I have one doubt
Suppose there is two jobs are running concurrently. First job created and populated the bean. In second step of same job, if I access the same bean using getBean() method, whether I will get bean which is created and populated in first step or system created a new bean? Please note, the bean should be thread safe.
The second job which is running in seperate thread do the same process but object should be different.
Please help to solve this issue.
Apr 29th, 2008, 12:37 PM
Our recommendation is to use a fresh application context for each job you launch - that way two jobs in separate threads cannot clash in the way that you are trying to avoid. Many components of a job are already stateful, so even if you weren't trying to save state between steps you would need to do that. You shouldn't need to do any lookups (getBean) - just inject the bean as a dependency into whatever objects need it.
But be very careful using a plain Spring bean to save state between steps. If your job fails in step 2, step 1 will not run again on a restart (unless you specifically set the allowStartIfComplete flag), so step 2 will fail because it hasn't had its state set up. If step 1 is expensive you might not want to run it on a restart, so that would be bad too. ExecutionContext and ItemStream were designed to persist step state between restarts, so if you need to make your job restartable and skip step 1 after it has completed successfully, have a careful look at those (plus documentation and framework implementations).
Apr 30th, 2008, 12:00 AM
Let me refine my requirement
We have more than 60 jobs which are scheduled on daily, monthly etc.
Application has UI to configure incoming source files. Once it is configured and triggered that job at scheduled time, the job should read that configuration data (file structure information) from data base and should store the data in well defined object. Then job is continuing the process of reading that configuration object. Please note that object contains the information needed for tokenize the file records and write incoming file into database.
So here I want
1. To make each job in separate thread which is working on its own space. The configure object should be isolated from other jobs.
2. This object is created at the time of reading from source file and the same object is using at the time of writing to database. Because the object contains the information needed for reading and writing.
3. I want to use only single context XML file to configure entire jobs.
My Tokenizer, Field set mapper and Dao classes have the ability to read any kind of file and insert/update those records into database. I have designed these classes and those are working fine.
Please help me.
Apr 30th, 2008, 06:11 AM
Nothing very unusual there. You might want to consider using a StepExectionListener to set up the format configuration from the database, instead of a separate step. That way there is no chance of a misunderstanding about restartability.
To help create a new application context for each job, look at the samples for the TaskEcecutorLauncher and the QuartzJobLauncher (they use a JobFactory implementation from the samples that manages the context creation).
Apr 30th, 2008, 07:04 AM
Yes.. we can use StepExectionListener to create the object which contains format configuration from the database. But here I want to access that object in itemReader and itemWriter to read the records from source file and write those into database.
So how can I get the reference of that object which is created in beforeStep() of StepExectionListener in itemReader and itemWriter classes?
Apr 30th, 2008, 08:04 AM
You just need to implement both interfaces (StepExecutionListener and ItemReader/Writer), either in the same object, or in two objects, one of which is injected into the other. If you also want to use one of the out-of-the-box reader/writers, this will involve delegating to that, so remember to register the delegate as a stream with the step (as per user guide).