2016-08-02 8 views
5

をスケジュールするために、私は春のブートバッチアプリケーションがあります。また、@EnableBatchProcessingで注釈さ@Configurationクラスでどのように春のブートバッチ・アプリケーション

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication 
public class LoadApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(LoadApplication.class, args); 
    } 
} 

を、私は次のバッチジョブBeanが定義されています:

@Bean 
public Job loadJob(JobBuilderFactory jobs, Step stepLoadFile, Step stepArchiveFile) { 
    return jobs.get("loadJob") 
      .incrementer(new RunIdIncrementer()) 
      .start(stepLoadFile) 
      .next(stepArchiveFile) 
      .build(); 
} 

バッチジョブのstepLoadFileはフラットファイル(下記参照)を読み取り、そのファイルデータをデータベースに書き込みます。 stepArchiveFileは、ファイルを別のディレクトリに移動します。

通常、ジョブは指定した時刻に1日に1回(火曜日〜土曜日)実行する必要があります。しかし、フラットファイルが見つからない場合、ジョブは失敗し、成功するか最大試行回数(例えば5回)になるまで30分ごとに再実行する必要がある。再実行が成功すると、次の通常の実行時間までジョブは再び実行されません。また、システムは理想的には同じジョブの同時実行を防止する必要があります。どのようにしてこれを行うことができますか?

注:再実行では、直前のジョブの実行が失敗した場所を選択する必要はありません。これは、チャンクサイズがファイル内の項目数より大きく設定されているためです。

私は私の@Configurationクラス(注:私は、構成およびメインクラスに@EnableRetryを追加しました):でこれを試してみました

@Bean 
public ItemReader<Test> reader(LineMapper<Test> lineMapper, ApplicationProperties properties) { 
    FlatFileItemReader<Test> flatFileItemReader = new FlatFileItemReader<Test>() { 
     @Override 
     @Retryable(value = {ItemStreamException.class}, maxAttempts=5) 
     public void open(ExecutionContext executionContext) throws ItemStreamException { 
      super.open(executionContext); 
     } 

     @Override 
     @Retryable(maxAttempts=5) 
     public Holding read() throws UnexpectedInputException, ParseException, Exception { 
      return super.read(); 
     } 

    }; 
    flatFileItemReader.setResource(new FileSystemResource(properties.getLoadFile())); 
    flatFileItemReader.setLineMapper(lineMapper); 
    return flatFileItemReader; 
} 

ItemStreamExceptionは再試行せずにスローされ、アプリケーションが終了されます。再試行が手順を失敗したため

答えて

6

あなたはLoadApplicationクラスの以下のコンポーネントを追加することにより、スケジュールすることができ

@Component 
@EnableScheduling 
class ScheduledTasks { 
@Autowired 
JobLauncher jobLauncher; 

@Autowired 
Job job; 

/**The pattern is a list of six single space-separated fields: 
* representing second, minute, hour, day, month, weekday. 
* Month and weekday names can be given as the first three letters of the English names. 
* Example patterns: 

    "0 0 * * * *" = the top of every hour of every day.* 
    "*\/10 * * * * *" = every ten seconds. Remove 2nd character, it is escape 
    "0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day. 
    "0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day. 
    "0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays 
    "0 0 0 25 12 ?" = every Christmas Day at midnight 

*/ 
@Scheduled(cron = "0 0/30 * * * TUE-SAT") 
public void runJob() throws Exception { 
    jobLauncher.run(job, new JobParameters()); 
} 
} 

あなたは春バッチを保存する場合は、ジョブ・ステップ自体も
<chunk reader="itemReader" writer="itemWriter" commit-interval="2" retry-limit="5"> <retryable-exception-classes> <include class="java.io.FileNotFoundException"/> </retryable-exception-classes> </chunk>

でそれを設定する必要がありますディスク上のメタデータテーブルをメモリの記憶域ではなく、バンプバッチで同じジョブを再度実行しないでください。

+0

応答をありがとう。残念ながら、私はこれが私が必要とするものを達成するとは思わない。ジョブは、通常、1日に1回だけ実行する必要があります。 '@ Scheduled'では、30分ごとに実行されます。ジョブが失敗した場合、成功するまで30分ごとに再実行する必要があります。 'retry-limit'では、30分待たずに直ちに再試行すると思います。また、「再試行制限」は仕事レベルではなくアイテムレベルにあるとも考えています。これらの点のいずれかが間違っている場合は、私を修正してください。 – James

0

ステップ宣言で条件付きフローを使用します。
<step id="readWrite"> <tasklet>(...)</tasklet> <next on="FAILED" to="scheduleNext" /> </step> <step id="scheduleNext"> <tasklet ref="schedulerTasklet"> </step> <bean id="schedulerTasklet" class="SchedulerTasklet"/>

とSchedulerTaskletスケジュールの次回実行:

public class SchedulerTasklet implements Tasklet { 
    @Autowired private TaskScheduler taskScheduler; 
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { 
     Runnable task = new Runnable() { 
      public void run() { 
       run your job here 
      } 
     }; 
     taskScheduler.schedule(task, delay); 
     return RepeatStatus.FINISHED; 
    } 
} 
関連する問題