2

複数のステップを持つ春のバッチジョブがあります。

ステップ 1 : データベースから 10 件のレコードをロードします。(Tasklet がその仕事をします)

ステップ 2: commit -interval =1 で ItemReader、ItemProcessor、ItemWriter の実装を使用して、ここで構成されたチャンク指向の処理

今私が理解しているように、すべてのレコードでこれが起こります

トランザクションの開始 (読み取り - 処理 - 書き込み) コミット Tx

  1. 私の問題は、6 つのレコードを処理し、7 番目のレコードで ItemProcessor 実装で例外が発生したと想像してください。ロールバックを試みますが、不明な状態のトランザクションのためにロールバックできません。

  2. 7 番目のレコードの tx をロールバックできなくても、8 番目、9 番目、10 番目のレコードはまったく処理されず、ジョブは停止します。

注: ItemProcessor 実装は、@Transactional(readOnly=false) アノテーションを使用してトランザクションとしてマークされたサービス (@Service アノテーション付き) を呼び出しています。

解決策を提案してください。

以下のItemProcessorコード

public Long process(LoanApplication loanApplication)throws Exception {
    Long createLoan = null;
    LoanStatus loanStatus = null;
    StaffUser user = staffUserService.getStaffUserByName(Constants.AUTO_USER);
    String notes = null;
    try{
        try{

            loanValidationService.validate(loanApplication);

            loanStatus=LoanStatus.U;

        }catch(LoanValidationException e){
            loanStatus=LoanStatus.UC;
            notes=e.getMessage();
        }

        dataLoadLoanManagementService.setText(notes);
        createLoan = dataLoadLoanManagementService.createLoan(loanApplication, user,loanStatus);
    }catch(Exception le){
        logger.error("Error creating the loan application ;  Parent Application Ref : " 
            + loanApplication
            + " with status as " +(loanStatus!=null ?loanStatus.getStatus():loanStatus)
            +"\n"
            +" School Ref :"
            + loanApplication.getSchoolRef()
            +"\n"
            +" Client Details :"
            +loanApplication.getClientDetails()
            + "Error Details: " + ExceptionUtils.getStackTrace(le));


    }   
    return createLoan;
}

スキップ可能な例外クラスが構成されていても、これは機能しません。
もう少し説明すると、Item Processor で Persistence Exception が発生し、それをキャッチするため、Spring バッチはライターを実行しますが、ライターの実行後に以下の例外が発生します

INFO  06-21 11:38:00 Commit failed while step execution data was already updated. Reverting to old version.  (TaskletStep.java:342) 
ERROR 06-21 11:38:00 Rolling back with transaction in unknown state  (TaskletStep.java:351) 
ERROR 06-21 11:38:00 Encountered an error executing the step  (AbstractStep.java:212)
org.springframework.transaction.TransactionSystemException: Could not commit JPA   transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
4

2 に答える 2

2

どちらの質問でも、プロセッサーフェーズ中に発生した例外をスキップすると問題が解決します。

skippable-exception-classes例外の根本的な原因がわかっている場合、これは要素ごとに構成できます。たとえば、プロセッサフ​​ェーズ中にゼロ除算の例外が発生し、それを無視したい場合、設定例は次のようになります。

<chunk reader="reader" processor="processor" writer="writer" 
commit-interval="1" >
<skippable-exception-classes>
<include class="java.lang.ArithmeticException" />
</skippable-exception-classes>
</chunk>

指定された例外クラスとそのサブクラスはスキップされるため、試してみることもできます。java.lang.Exception

于 2012-06-20T15:13:51.167 に答える
2

loanValidationService.validate でトランザクション伝播オプションを確認してください

「rollbackOnly としてマークされたトランザクション」、「ステップ実行データが既に更新されている間にコミットに失敗しました」から推測

現在のトランザクションはロールバックされ、親トランザクションはコミットされるべきですが、トランザクションは既に終了しています。

チャンクのトランザクションが LoanValidationService.validate で同じ場合

伝播オプションを REQUIRES_NEW に変更します

次の記事は、メタデータのトランザクションを理解するのに役立つ場合があります。 http://blog.codecentric.de/en/2012/03/transactions-in-spring-batch-part-1-the-basics/

    class LoanValidationServiceImpl implements LoanValidationService {
        @Trasnactional(propagation=REQUIRES_NEW, rollbackFor=Exception.class)
        validate(LoanApplication loanApplication) {
             // business logic
        }
    }
于 2013-03-07T03:00:35.017 に答える