提问者:小点点

批处理作业因JobExecutionAlreadyRunningException而失败:此作业的作业执行已在运行


如何从main方法停止批处理作业?我正在从我的方法运行批处理作业,现在它给我以下错误。有关如何终止和停止它的任何帮助?

A job execution for this job is already running: JobInstance: id=18380, version=0, Job=[myFileGenerationJob]
org.springframework.batch.core.repository.JobExecutionAlreadyRunningException: A job execution for this job is already running: JobInstance: id=18380, version=0, Job=[myFileGenerationJob]
Done
    at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:120)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:172)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    at com.sun.proxy.$Proxy3.createJobExecution(Unknown Source)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:125)
    at com.mastercard.ess.eds.CustomerFileGenerationApp.main(CustomerFileGenerationApp.java:31)

我正在使用以下代码-

public class CustomerFileGenerationApp {

    public static void main(String[] args) {
        PropertyConfigurator.configure("src/main/resources/log4j.properties");
        String[] springConfig = { "../META-INF/spring/customer-file-generation-job.xml"};

        ApplicationContext context = new FileSystemXmlApplicationContext(springConfig);

        JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
        Job job = (Job) context.getBean("customerFileGenerationJob");

        JobParameters jobParameters = new JobParametersBuilder().addString("runMode", "ABCD").toJobParameters();

        try {
            JobExecution execution = jobLauncher.run(job, jobParameters);
            System.out.println("Exit Status : " + execution.getStatus());
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }

        System.out.println("Done");
    }

}

共1个答案

匿名用户

不幸的是,我不知道使用java代码来处理该异常。但是,您可以通过使用一些查询更新相关的批处理元表数据来管理该异常。

您应该检查两个表,batch_step_execution,batch_job_execution。(我假设您已经创建了它们,因为Spring Batch将它们提供给几乎所有类型的数据库。)

如果这些表具有已启动(启动)和未完成的作业,则在重新启动服务器时可能会遇到上述异常。

因此,首先,您可以通过执行下面的查询来检查正在运行的作业是否存在。

SELECT  STEP_EXECUTION_ID
        , JOB_EXECUTION_ID
        , STEP_NAME
        , STATUS
        , EXIT_CODE
        , bse.*
FROM batch_step_execution bse
WHERE 1=1
AND status IN ('STARTED', 'STARTING')
AND exit_code NOT IN ('COMPLETED', 'FAILED')
ORDER BY start_time desc
;

SELECT bje.JOB_EXECUTION_ID
        , bji.JOB_NAME
        , bje.JOB_INSTANCE_ID
        , bje.STATUS
        , bje.EXIT_CODE
        , timediff(bje.CREATE_TIME, NOW()) 
        , bje.*
FROM batch_job_execution bje
INNER JOIN batch_job_instance bji
ON bje.job_instance_id = bji.job_instance_id
WHERE 1=1
AND status IN ('STARTED', 'STARTING')
AND exit_code NOT IN ('COMPLETED', 'FAILED')
ORDER BY bje.create_time desc
;

其次,如果上面有行,您可以通过执行下面的查询将这些作业更新为COMPLETED状态。

UPDATE 
    batch_step_execution 
SET END_TIME = now()
    ,LAST_UPDATED = now() 
    ,STATUS = 'COMPLETED' 
    ,EXIT_CODE = 'FAILED' 
WHERE 
    STEP_EXECUTION_ID in (
        select STEP_EXECUTION_ID 
        from batch_step_execution bse 
        where 1=1
        and status not in ('COMPLETED', 'FAILED')
        or EXIT_CODE not in ('COMPLETED', 'FAILED') 
    )
;

UPDATE 
    BATCH_JOB_EXECUTION 
SET 
    END_TIME = now() 
    ,LAST_UPDATED = now() 
    ,STATUS = 'COMPLETED' 
    ,EXIT_CODE = 'FAILED' 
WHERE 
   JOB_EXECUTION_ID in (
        select bje.JOB_EXECUTION_ID
        from batch_job_execution bje 
        where 1=1
        and (status not in ('COMPLETED', 'FAILED'))
        or (EXIT_CODE not in ('COMPLETED', 'FAILED'))
   )
;

第三,请重新启动服务器。在我的例子中,当我遇到JobExecutionAlreadyRunningException时,它会起作用。

谢谢。