Konfigurasi Skip Logic di Spring Batch

1. Perkenalan

Secara default, setiap kesalahan yang ditemui selama pemrosesan pekerjaan Batch Musim Semi akan membuat langkah terkait gagal. Namun, ada banyak situasi di mana kami lebih suka melewatkan item yang saat ini diproses untuk pengecualian tertentu.

Dalam tutorial ini, kita akan menjelajahi dua pendekatan untuk mengonfigurasi logika lewati dalam kerangka kerja Spring Batch.

2. Kasus Penggunaan Kami

Untuk tujuan contoh, kami akan menggunakan kembali pekerjaan sederhana berorientasi potongan yang sudah disajikan di artikel pengantar Spring Batch kami.

Pekerjaan ini mengubah beberapa data keuangan dari CSV ke format XML.

2.1. Memasukan data

Pertama, mari tambahkan beberapa baris ke file CSV asli:

username, user_id, transaction_date, transaction_amount devendra, 1234, 31/10/2015, 10000 john, 2134, 3/12/2015, 12321 robin, 2134, 2/02/2015, 23411 , 2536, 3/10/2019, 100 mike, 9876, 5/11/2018, -500 , 3425, 10/10/2017, 9999

Seperti yang bisa kita lihat, tiga baris terakhir berisi beberapa data yang tidak valid - baris 5 dan 7 tidak memiliki kolom nama pengguna, dan jumlah transaksi di baris 6 negatif.

Di bagian selanjutnya, kami akan mengonfigurasi tugas batch kami untuk melewati catatan yang rusak ini.

3. Mengonfigurasi Batas Lewati dan Pengecualian yang Dapat Diabaikan

3.1. Menggunakan skip dan skipLimit

Sekarang mari kita bahas yang pertama dari dua cara untuk mengonfigurasi pekerjaan kita untuk melewati item jika terjadi kegagalan - metode skip dan skipLimit :

@Bean public Step skippingStep( ItemProcessor processor, ItemWriter writer) throws ParseException { return stepBuilderFactory .get("skippingStep") .chunk(10) .reader(itemReader(invalidInputCsv)) .processor(processor) .writer(writer) .faultTolerant() .skipLimit(2) .skip(MissingUsernameException.class) .skip(NegativeAmountException.class) .build(); }

Pertama-tama, untuk mengaktifkan fungsionalitas lewati, kita perlu menyertakan panggilan ke faultTolerant () selama proses pembuatan langkah.

Dalam skip () dan skipLimit () , kita mendefinisikan pengecualian yang ingin kita lewati dan jumlah maksimum item yang dilewati.

Dalam contoh di atas, jika MissingUsernameException atau NegativeAmountException dilempar selama fase baca, proses, atau tulis, maka item yang saat ini diproses akan dihilangkan dan dihitung terhadap batas total dua.

Akibatnya, jika ada pengecualian yang dilakukan untuk ketiga kalinya, seluruh langkah akan gagal .

3.1. Menggunakan noSkip

Pada contoh sebelumnya, pengecualian lain selain MissingUsernameException dan NegativeAmountException membuat langkah kita gagal.

Namun, dalam beberapa situasi, mungkin lebih tepat untuk mengidentifikasi pengecualian yang akan membuat langkah kita gagal dan melewati langkah lainnya.

Mari kita lihat bagaimana kita dapat mengonfigurasi ini menggunakan skip , skipLimit , dan noSkip :

@Bean public Step skippingStep( ItemProcessor processor, ItemWriter writer) throws ParseException { return stepBuilderFactory .get("skippingStep") .chunk(10) .reader(itemReader(invalidInputCsv)) .processor(processor) .writer(writer) .faultTolerant() .skipLimit(2) .skip(Exception.class) .noSkip(SAXException.class) .build(); }

Dengan konfigurasi di atas, kami menginstruksikan framework Spring Batch untuk melewati Pengecualian apa pun (dalam batas yang dikonfigurasi) kecuali SAXException . Ini berarti SAXException selalu menyebabkan kegagalan langkah.

Urutan panggilan skip () dan noSkip () tidak menjadi masalah.

4. Menggunakan SkipPolicy Kustom

Terkadang kita mungkin membutuhkan mekanisme pemeriksaan lewati yang lebih canggih. Untuk tujuan itu, framework Spring Batch menyediakan antarmuka SkipPolicy .

Kami kemudian dapat menyediakan implementasi logika lewati kami sendiri dan memasukkannya ke dalam definisi langkah kami.

Dengan mengingat contoh sebelumnya, bayangkan kita masih ingin menetapkan batas lewati dua item dan hanya membuat MissingUsernameException dan NegativeAmountException yang dapat diabaikan.

Namun, kendala tambahannya adalah kita dapat melewati NegativeAmountException, tetapi hanya jika jumlahnya tidak melebihi batas yang ditentukan .

Mari terapkan SkipPolicy kustom kita :

public class CustomSkipPolicy implements SkipPolicy { private static final int MAX_SKIP_COUNT = 2; private static final int INVALID_TX_AMOUNT_LIMIT = -1000; @Override public boolean shouldSkip(Throwable throwable, int skipCount) throws SkipLimitExceededException { if (throwable instanceof MissingUsernameException && skipCount < MAX_SKIP_COUNT) { return true; } if (throwable instanceof NegativeAmountException && skipCount < MAX_SKIP_COUNT ) { NegativeAmountException ex = (NegativeAmountException) throwable; if(ex.getAmount() < INVALID_TX_AMOUNT_LIMIT) { return false; } else { return true; } } return false; } }

Sekarang, kita dapat menggunakan kebijakan kustom kita dalam definisi langkah:

 @Bean public Step skippingStep( ItemProcessor processor, ItemWriter writer) throws ParseException { return stepBuilderFactory .get("skippingStep") .chunk(10) .reader(itemReader(invalidInputCsv)) .processor(processor) .writer(writer) .faultTolerant() .skipPolicy(new CustomSkipPolicy()) .build(); }

Dan, mirip dengan contoh kami sebelumnya, kami masih perlu menggunakan faultTolerant () untuk mengaktifkan fungsionalitas lewati.

Kali ini, bagaimanapun, kami tidak memanggil skip () atau noSkip () . Sebagai gantinya, kami menggunakan metode skipPolicy () untuk menyediakan implementasi antarmuka SkipPolicy kami sendiri .

Seperti yang bisa kita lihat, pendekatan ini memberi kita lebih banyak fleksibilitas, sehingga bisa menjadi pilihan yang baik dalam kasus penggunaan tertentu .

5. Kesimpulan

Dalam tutorial ini, kami menyajikan dua cara untuk membuat pekerjaan Spring Batch toleran terhadap kesalahan.

Meskipun menggunakan metode skipLimit () bersama-sama dengan skip () dan noSkip () tampaknya lebih populer, kami mungkin menemukan penerapan SkipPolicy kustom lebih nyaman dalam beberapa situasi.

Seperti biasa, semua contoh kode tersedia di GitHub.