Akhirnya saya berhasil membuatnya bekerja tetapi dengan beberapa modifikasi. Idenya adalah menggunakan LockModeType.PESSIMISTIC_FORCE_INCREMENT alih-alih PESSIMISTIC_WRITE. Dengan menggunakan mode kunci ini, Cron Jobs berperilaku sebagai berikut:
- Saat pekerjaan pertama membuat pilihan untuk pembaruan, semuanya berjalan seperti yang diharapkan tetapi versi pada objek berubah.
- Jika pekerjaan lain mencoba membuat pilihan yang sama saat yang pertama masih dalam transaksinya, JPA meluncurkan OptimisticLockException sehingga jika Anda menangkap pengecualian itu, Anda dapat yakin bahwa itu dilemparkan untuk kunci baca.
Solusi ini memiliki berbagai mitra:
- SynchronizedCronJobTask harus memiliki bidang versi dan berada di bawah kontrol versi dengan @Version
- Anda perlu menangani OptimisticLockException, dan itu harus ditangkap di luar metode layanan transaksional untuk melakukan rollback saat de lock terjadi.
- IMHO adalah solusi yang tidak elegan, jauh lebih buruk dari sekadar kunci tempat Cron Jobs menunggu Pekerjaan sebelumnya selesai.