2017-08-30 18 views
0

ライターで再試行を使用しているバネバッチがあります。筆者はこのようになります:「DB操作2」で例外がある場合スプリングバッチライターで再試行

public class MyWriter implements ItemWriter<MyClass> { 

    @Retryable(maxAttempts=3, [email protected](delay=2000)) 
    public void write(List<? extends MyClass> list) throws Exception { 
    // db operation 1 -- insert query 
    // some business logic 
    // db operation 2 -- update query 
    } 
} 

、再試行と呼ばれ、期待通りに実行が再び「DB操作1」から開始します。しかし、 'db operation 1'は挿入クエリであり、今回は同じレコードを再度挿入しようとすると例外がスローされます(DBのユニーク制約は失敗します)。最終的に、バッチは3回試行した後に失敗し、このステップの何もデータベースにコミットされません。

再試行する前に 'db operation 1'をロールバック/フラッシュしてはいけませんか?これは予想される動作か、実装に何か問題がありますか?

私はSpringブートアプリケーションとspring jdbcを使用しています。

答えて

0

このように再試行しないでください。 Spring Batchのリトライロジックを使用します。 Spring Batchはトランザクションをロールバックし、安全な方法で再試行します。あなたのリトライをやり直す方法では、再試行はトランザクションと調整されないので、レコードが重複している(トランザクションがロールバックされなかったため)。

+0

それは...助けてくれてありがとう! – Sakshi

0

spring jdbcでは、トランザクションマネージャを使用しています。これを使用して、トランザクション境界の設定を制御し、更新クエリの後にコミットします。

thisも参照してください。トランザクションマネージャの使用方法の例を示します。

+0

私はバネバッチがトランザクションを独自に管理するため、トランザクションマネージャを設定していません。トランザクションは期待どおりに動作しており、コミットは更新クエリの後でのみ発生しています。問題は、まだコミットされていないにもかかわらず、再試行ですでに挿入が発生していると考えていることです。 – Sakshi