如何在设置并发限制后立即获取作业ID

时间:2014-08-07 01:04:58

标签: java spring spring-batch

问题是,在我设置并发限制(例如限制为2)后,当第3个请求进入时,作业启动器将不会返回作业执行(作业启动程序阻止新作业执行) )。换句话说,我想通过运行" runFun()"获得请求后立即获取作业ID。方法

我尝试了SimpleAsyncTaskExecutor和SimpleThreadPoolTask​​Executor,它们都无法正常工作。而且因为挂起了#la; jobLauncher.run()"方法,前作业监听器也没有作业ID信息。我浏览了源代码(SimpleAsyncTaskExecutor.execute(),ConcurrencyThrottleSupport.beforeAccess()),没有运气来解决这个问题。

在这种情况下,当作业启动器运行执行时,如何立即获取作业ID?

我将主要代码发布如下:

**//Config:**

<bean id="jobLauncher"
      class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository"/>
    <property name="taskExecutor">
        <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor">
            <property name="concurrencyLimit" value="2"/>
        </bean>
    </property>
</bean>

<bean id="jobExplorer" class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean">
    <property name="dataSource" ref="sampleservice.persist.datasource"/>
</bean>

<bean id="jobOperator" class="org.springframework.batch.core.launch.support.SimpleJobOperator">
    <property name="jobExplorer" ref="jobExplorer"/>
    <property name="jobRepository" ref="jobRepository"/>
    <property name="jobLauncher" ref="jobLauncher"/>
    <property name="jobRegistry" ref="jobRegistry"/>
</bean>

<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"></bean>


**//Code:**

    Private Long runFun() {
    new JobParametersBuilder()
                    .addLong("pId", parameterDO.getPId())
                    .toJobParameters();

                try {
                    JobExecution jobExecution = jobLauncher.run(bulkDownloadJob, params);

    //the job execution id will be blocked with status "STARTING" in the batch metadata table until the job is actually started with status "STARTED"
                    return jobExecution.getId();  
    } catch ...

}

在思考之后,我正在尝试创建一个新的作业启动器,它创建一个专门执行作业的新线程并立即返回jobExecution:

//NewLauncherClass
public JobExecution run(final Job job, final JobParameters jobParameters) {

    ... 

    jobExecution = jobRepository.createJobExecution(job.getName(), jobParameters);

        try {
            return jobExecution;
        } finally {
            if (jobExecution != null) {
                new Thread(new Runnable() {
                    public void run() {
                        executeJob(jobExecution, job, jobParameters);
                    }
                }).start();
            } else {
                logger.error("*****");
            }
        }

    }

    //added this method for executing the job
    private void executeJob(final JobExecution jobExecution, final Job job, final JobParameters jobParameters) {
        try {
            logger.info("***** test bulk *****  Job " + jobExecution.getId() + " is going to be executed");

            taskExecutor.execute(new Runnable() {

                ...

1 个答案:

答案 0 :(得分:0)

您尝试执行的操作不适用于SimpleJobLauncher。问题是TaskExecutor将阻塞,直到有一个线程可用于在使用限制时执行任务。问题是你必须有一种方法可以在线程可用之前返回JobExecution

你必须做你正在尝试的消息传递。当前基于消息的组件不会执行此操作,但您可以创建JobLauncher创建JobExecution并将其发送到MessageHandler以执行它。这将允许调用者返回JobExecution并仍然等待执行作业。