Di salah satu langkah pekerjaan Spring Batch saya, saya mencoba mengkonfigurasinya sehingga ketika ObjectOptimisticLockingFailureException terjadi, langkah itu dapat dicoba lagi dan semoga percobaan ulang akan berhasil.

  @Bean
  public Step myStep(StaxEventItemReader<Response> staxEventResponseReader,
      ItemWriter<Response> itemWriter,
      ItemProcessor<? super Response, ? extends Response> responseProcessor) {
    return stepBuilderFactory.get("myStep")
        .<Response, Response>chunk(1)
        .reader(staxEventResponseReader)
        .processor(responseProcessor)
        .writer(itemWriter)
        //.faultTolerant().retryLimit(3).retry(Exception.class)
        .build();
  }

Logika penulis untuk langkah ini cukup sederhana: ia mencoba membaca baris dari database, dan setelah menemukan baris, ia memperbaruinya. Saya dapat mereproduksi ObjectOptimisticLockingFailureException dengan menyetel breakpoint tepat setelah metode find, secara manual menabrak kolom version untuk baris dalam database dan mengkomitnya, lalu melanjutkan.

Namun, setelah menghapus komentar definisi coba lagi di langkah saya, tidak ada percobaan ulang yang dicoba. Setelah beberapa debugging, tampaknya logika percobaan ulang Spring ada di dalam transaksi chunk; tetapi karena ObjectOptimisticLockingFailureException tidak dilemparkan oleh kode saya di penulis, tetapi oleh transaksi potongan Spring yang melakukan logika, tidak ada percobaan ulang sama sekali.

Chunk Transaction Begin
    Begin Retry loop in FaultTolerantChunkProcessor.write()
        Writer logic in my Step
    End Retry loop
Chunk Transaction Commit - Throws ObjectOptimisticLockingFailureException

Ketika saya mencoba untuk secara eksplisit melemparkan ObjectOptimisticLockingFailureException di penulis saya, logika coba lagi bekerja dengan sempurna seperti yang diharapkan. Pertanyaan saya adalah:

  1. Bagaimana cara membuat logika coba lagi berfungsi jika pengecualian tidak dilemparkan dari kode penulis saya di langkah, tetapi pada saat transaksi potongan dilakukan oleh Spring Batch?
  2. Perilaku aneh lainnya adalah, ketika saya secara manual menyebabkan ObjectOptimisticLockingFailureException dengan menabrak kolom versi di database, dengan definisi coba lagi yang dikomentari di langkah, status akhir dari langkah tersebut adalah GAGAL yang diharapkan. Tetapi dengan definisi coba lagi yang tidak dikomentari, status akhir dari langkah tersebut adalah LENGKAP. Mengapa demikian?
0
xli 22 April 2020, 23:57

1 menjawab

Jawaban Terbaik
  1. Bagaimana cara membuat logika coba lagi bekerja jika pengecualian tidak dikeluarkan dari kode penulis saya di langkah, tetapi pada saat transaksi potongan dilakukan oleh Spring Batch?

Ada masalah terbuka untuk itu di sini: https://github.com/spring -projects/spring-batch/issues/1826. Solusinya adalah (mencoba mengantisipasi dan) membuang pengecualian apa pun yang mungkin terjadi pada waktu komit di penulis. Ini yang sudah Anda coba dan konfirmasikan yang berfungsi saat Anda mengucapkan When I tried to explicitly throw ObjectOptimisticLockingFailureException in my writer, the retry logic worked perfectly as expected.

  1. Perilaku aneh lainnya adalah, ketika saya secara manual menyebabkan ObjectOptimisticLockingFailureException dengan menabrak kolom versi di database, dengan definisi coba lagi yang dikomentari di langkah, status akhir dari langkah tersebut adalah GAGAL yang diharapkan. Tetapi dengan definisi coba lagi yang tidak dikomentari, status akhir dari langkah tersebut adalah LENGKAP. Kenapa begitu?

Ini terkait dengan masalah sebelumnya, tetapi disebabkan oleh masalah yang berbeda: https:/ /github.com/spring-projects/spring-batch/issues/1189. Karena itu, boleh saja bermain dengan bidang version selama sesi debug untuk memahami cara kerjanya, tetapi saya tidak merekomendasikan untuk mengubah kolom version dalam kode Anda. Musim Semi reli pada kolom ini sangat dalam strategi penguncian optimis, dan tidak diharapkan untuk mengubah nilai kolom ini dalam kode pengguna, jika tidak, perilaku yang tidak diharapkan mungkin terjadi.

1
Mahmoud Ben Hassine 23 April 2020, 14:11