2017-05-17 9 views
0

私のSpring Batchアプリケーションでは、内部的にDynamoDBAsyncClientを使用してDynamoDBにアイテムを書き込むCustomItemWriterを作成しました。このクライアントはFutureオブジェクトを返します。何百万というレコードを持つ入力ファイルがあります。 CustomItemWriterは、すぐに私のバッチジョブが5秒以内にCOMPLETEDというステータスで終了しますが、実際にはDBにすべてのアイテムを書き込むのに3〜4分かかるので、そのバッチジョブはDataBaseに書き込まれたすべてのアイテムの後に終了します。どうやってやるの?Exitを指定したSpringバッチ終了ステータス:実際のジョブが完了する前に完了しましたか?

ジョブはそれが待機しない、その戻り将来オブジェクトItemWriterにおけるので

public class CustomeWriter implements ItemWriter<Report>{ 
    public void write(List<? extends Report> item) throws Exception { 
    List<Future<PutItemResult>> list = new LinkedList(); 
    AmazonDynamoDBAsyncClient client = new AmazonDynamoDBAsyncClient(); 
     for(Report report : item) { 
      PutItemRequest req = new PutItemRequest(); 
      req.setTableName("MyTable"); 
      req.setReturnValue(ReturnValue.ALL_ODD); 
      req.addItemEntry("customerId",new 
      AttributeValue(item.getCustomeId())); 
      Future<PutItemResult> res = client.putItemAsync(req); 
      list.add(res); 
      } 
    } 

} 

以下メインクラスが

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

を含有するようCustomeItemWriterが定義されている

<bean id="report" class="com.solution.model.Report" scope="prototype" /> 
     <batch:job id="job" restartable="true"> 
      <batch:step id="step1"> 
       <batch:tasklet> 
        <batch:chunk reader="cvsFileItemReader" processor="filterReportProcessor" writer="customItemWriter" 
         commit-interval="20"> 
        </batch:chunk> 
       </batch:tasklet> 
      </batch:step> 
     </batch:job> 
<bean id="customItemWriter" class="com.solution.writer.CustomeWriter"></bean> 

以下のように定義されますoprationを完了する。そして、すべてのアイテムが作成のために提出されたので、メインからはバッチステータスがCOMPLETEDと表示され、ジョブは終了します。 このジョブは、実際の書き込みがDynamoDBで実行された後に終了する必要があります。 リスナーが利用可能であるか、これを待つことができますか?

+0

は、我々はあなたのライターコード – pvpkiran

+0

は、コードを更新しました見ることができ、あなたのXMLで同じことを行う必要があり、Javaコードです。 –

+1

実際に完了するまでライターをブロックすべき 'Future'の結果を取得します。 –

答えて

1

ここに1つのアプローチがあります。 ItemWriter::writeは何も返さないので、リスナー機能を利用することができます。

@Component 
@JobScope 
public class YourWriteListener implements ItemWriteListener<WhatEverYourTypeIs> { 


    @Value("#{jobExecution.executionContext}") 
    private ExecutionContext executionContext; 


    @Override 
    public void afterWrite(final List<? extends WhatEverYourTypeIs> paramList) { 
    Future future = this.executionContext.readAndValidate("FutureKey", Future.class); 
    //wait till the job is done using future object 
    } 

    @Override 
    public void beforeWrite(final List<? extends WhatEverYourTypeIs> paramList) { 

    } 

    @Override 
    public void onWriteError(final Exception paramException, final List<? extends WhatEverYourTypeIs> paramList) { 

    } 
} 

writerクラスでは、将来のオブジェクトをExecutionContextに追加する以外はすべて同じです。

public class YourItemWriter extends ItemWriter<WhatEverYourTypeIs> { 

    @Value("#{jobExecution.executionContext}") 
    private ExecutionContext executionContext; 

    @Override 
    protected void doWrite(final List<? extends WhatEverYourTypeIs> youritems) 

    //write to DynamoDb and get Future object 
    executionContext.put("FutureKey", future); 
    } 

    } 

}

そして、あなたはあなたの設定でリスナーを登録することができます。ここでは、

@Bean 
    public Step initStep() { 

    return this.stepBuilders.get("someStepName").<YourTypeX, YourTypeY>chunk(10) 
     .reader(yourReader).processor(yourProcessor) 
     .writer(yourWriter).listener(YourWriteListener) 
     .build(); 
    } 
関連する問題