2014-03-19 79 views
2

所以我有兩個工作,每個都有獨立的tasklet。Spring批處理和彈簧TaskScheduler

職吧將做:

sysout("JobA executed at "+new Date()); 

JOBB將做:

sysout("JobB executed at "+new Date()); 

這兩者可以是在一個單獨的XML或者在一個XML。但我目前有兩個單獨的XML。我定義了兩個作業用同樣的方法是這樣的:

<batch:job id="task_scheduler" restartable="false"> 
    <batch:step id="test_task_scheduler" 
     allow-start-if-complete="true"> 
     <batch:tasklet ref="job1" /> 
    </batch:step> 
</batch:job> 

<bean id="job1" class="com.irsis.batch.tasklet.TestOut" /> 
<bean id="runScheduler" class="com.irsis.batch.taskscheduler.RunScheduler1" /> 

然後在我application-context.xml我定義的任務調度

<task:scheduled-tasks> 
    <task:scheduled ref="runScheduler1" method="run" 
     cron="*0 0/1 * 1/1 * ? " /> 
    <task:scheduled ref="runScheduler2" method="run" 
     cron="0 0/2 * 1/1 * ? "/> 
</task:scheduled-tasks> 

當運行我有這樣的例外

Could not autowire field: org.springframework.batch.core.Job com.irsis.batch.taskscheduler.RunScheduler1.job; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.batch.core.Job] is defined: expected single matching bean but found 2: task_scheduler,task_scheduler2 

順便說一句,這是我的RunScheduler1.java文件

@Autowired 
JobLauncher jobLauncher; 

@Autowired 
Job job; 

public void run() { 


    try { 

     String dateParam = new Date().toString(); 
     JobParameters param = new JobParametersBuilder().addString("date", 
       dateParam).toJobParameters(); 

     JobExecution execution = jobLauncher.run(job, param); 
     System.out.println("Exit Status : " + execution.getStatus()); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    System.out.println("Done"); 

} 

現在我的問題是春季批處理可能有多個作業嗎?因爲從我看到的例外是,它只是期待一份工作。

雖然我嘗試了另一種方式。我所做的是在應用程序的context.xml

<batch:job id="job" restartable="false"> 
    <batch:step id="test_task_scheduler" 
     allow-start-if-complete="true"> 
     <batch:tasklet ref="job1" /> 
    </batch:step> 
</batch:job> 

<bean id="job1" class="com.irsis.batch.tasklet.TestOut" /> 
<bean id="runScheduler1" class="com.irsis.batch.taskscheduler.RunScheduler1" /> 


    <batch:job id="job2" restartable="false"> 
    <batch:step id="test_task2_scheduler" 
     allow-start-if-complete="true"> 
     <batch:tasklet ref="job2" /> 
    </batch:step> 
</batch:job> 

<bean id="job2" class="com.irsis.batch.tasklet.TestOut2" /> 
<bean id="runScheduler2" class="com.irsis.batch.taskscheduler.RunScheduler2" /> 


<task:scheduled-tasks> 
    <task:scheduled ref="runScheduler1" method="run" 
     cron="*0 0/1 * 1/1 * ? " /> 

</task:scheduled-tasks> 

<task:scheduled-tasks> 
    <task:scheduled ref="runScheduler2" method="run" 
     cron="0 0/2 * 1/1 * ? " /> 
</task:scheduled-tasks> 

它跑的第一份工作,然後每當它試圖運行第二個作業出現此異常這樣的事情:

PreparedStatementCallback; SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION)
values (?, ?, ?, ?)]; ERROR: duplicate key value violates unique constraint "job_inst_un" Detail: Key (job_name, job_key)=(job, 8a87688793625c6f3b8f982dbe6689d2) already exists.; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "job_inst_un" Detail: Key (job_name, job_key)=(job, 8a87688793625c6f3b8f982dbe6689d2) already exists.

更新:我想我會改變我的方法。另一個問題鏈接here

感謝,
噴氣

回答

3

這是不是一個春天批次例外,它更是一個正常的春季線路異常。原因是您的RunScheduler1中可能有Job物業的@Autowired註釋。現在,在您的環境下,你最終有兩個作業的一個與task_scheduler和一個ID與ID的task_scheduler2和Spring不知道你要線在特定的一個。

一個簡單的解決方法將是簡單地刪除@Autowired並注入通過XML參考這種方式:

<bean id="runScheduler" class="com.irsis.batch.taskscheduler.RunScheduler1" > 
    <property name="job" ref="task_scheduler"/> 
</bean> 

更新: 你唯一約束相關的異常實際上是可能的 - 兩個作業被認爲是相同的,如果兩個作業的參數完全匹配,這,你的情況不知怎的,日期是衝突的(我有一個與Spring批處理的小bug因爲Date的toString方法的精度),因此對於兩個不同的作業實例,因此也是問題。我可以建議增加一個參數(例如使用UUID.randomUUID().toString()來表示您的自定義UUID),這將確保兩個作業參數是絕對唯一的,並且應該被視爲兩個完全不同的作業實例。

+0

喜@BijuKunjummen我編輯我的問題。我添加了RunScheduler1.java文件以供參考。 –

+0

劃傷我以前的評論。能夠運行該項目,但是無論何時開始執行作業,它都會捕獲異常。 「工作不能爲空。」 –

+0

我可以推薦簡單地結束您當前的問題,並針對您的具體問題重新開放 - 現在您已經提到了3個不同的問題,並且我已經爲其中2個提供了答案。 –

1

我認爲你一次又一次地傳遞相同的工作參數...來運行這個工作。 嘗試更改每次運行的作業參數。

like--

JobParameters jobParameters = new JobParametersBuilder() 
      .addLong("time",System.currentTimeMillis()) 
      .toJobParameters(); 

JobExecution execution = jobLauncher.run(job, jobParameters); 
相關問題