2016-08-05 37 views
0

区切られたファイルからデータを読み取り、JdbcBatchItemWriterを使用してDBに書き込むFlatFileItemReaderを使用して、バッチバッチジョブを作成しました。私のsetpの設定は以下の通りです。シングルトランザクションでのバッチ処理タスクレット

<batch:step id="step1"> 
     <batch:tasklet> 
      <batch:chunk reader="fileReader" 
       writer="dbWriter" commit-interval="100"> 
      </batch:chunk> 
     </batch:tasklet> 
</batch:step> 

障害がタスクレットが完了する前に発生するので、もし上記の構成は、私は以前にコミットされた行を戻すことができない(ステップ-1)、各100rowsに別々のトランザクションを開いています。単一のトランザクションでタスクレット全体を実行する方法はありますか。

P.S:ジョブ・リポジトリとしてMapJobRepositoryFactoryBeanを使用しています。再起動のためにデータベースにメタ・テーブルを作成したくありません。

答えて

1

Springバッチでは、ジョブのために一度に1つのトランザクションしか常に存在しません。

トランザクションがステップの始めに開かれ、ステップの最後にコミットされることがわかるように、下の図に注目してください。実際に

Spring Batch transaction management

Image Source

、春のバッチを使用しての主な利点の一つは、開発者ドンとして、我々はトランザクション管理を心配しなければならないことです。障害が発生しても、コミットされていないトランザクション全体が自動的にロールバックされます。

0

(私はSpring Batchを最後に使用して以来、しばらくしていましたが、私の理解はまだ有効です:P)チャック指向のタスクレットを使用するのではなく、単純なタスクレットを1つ作成するだけです。デフォルトでは、単純なタスクレットは単一のトランザクションで実行されます。

public class ReaderWriterTasklet<T> implements Tasklet { 
    private ItemReader<T> reader; 
    private ItemWriter<T> writer; 
    // and corresponding setters 

    public RepeatStatus execute(StepContribution contribution, 
        ChunkContext chunkContext) { 
     List<T> chunk = new LinkedList<T>(); 
     while (true) { 
      T item = reader.read(); 
      if (item == null) { 
       break; 
      } else { 
       chunk.add(item); 
      } 
     } 
     writer.write(chunk); 
     return RepeatStatus.FINISHED; 
    } 
} 

は(私はあなたが既に知っている必要があると信じて:あなたはすでにリーダライタを内蔵していることを考えると、あなたは(あなたのアイデアを表示するだけの擬似コードを)やっているチャック指向のステップを模倣タスクレットを書くことができますどのようにタスクレットを実行するステップを定義するのですか?私はそれをスキップします)

もう一つの汚い方法は、チャンクを使い続け、コミット間隔をInteger.MAX_VALUEに設定することです。そうすることで、チャンク指向のステップは、最後に到達するまでリーダーからアイテムを取得し続け、1つのトランザクション内で起こる1つの大きなチャンクでライターに書き込みます。