javax.persistence.lock.timeout juga tidak berfungsi untuk saya ketika disediakan seperti di bawah ini
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout",value = "15000")})
Tetapi kemudian saya mencoba sesuatu yang lain yang berhasil. Alih-alih menggunakan @Repository dan menggunakan CrudRepository, sekarang saya mengonfigurasi hibernasi saya menggunakan manajer entitas. CreateQuery yang digunakan bersama dengan lock dan setting lock timeout. Dan konfigurasi ini berfungsi seperti yang diharapkan. Saya memiliki dua transaksi yang berjalan secara paralel dan mencoba mengunci baris yang sama persis di DB. Transaksi pertama dapat memperoleh kunci MENULIS dan menahan kunci selama sekitar 10 detik sebelum melepaskan kunci. Sementara itu, transaksi kedua mencoba untuk mendapatkan kunci pada baris yang sama tetapi karena javax.persistence.lock.timeout diatur ke 15 detik, ia menunggu kunci dilepaskan dan kemudian memperoleh kuncinya sendiri. Oleh karena itu, buatlah alurnya menjadi serial.
@Component
public class Repository {
@PersistenceContext
private EntityManager em;
public Optional<Cache> getById(int id){
List<Cache> list = em.createQuery("select c from Cache c where c.id = ?1")
.setParameter(1, id)
.setHint("javax.persistence.lock.timeout", 15000)
.setLockMode(LockModeType.PESSIMISTIC_WRITE)
.getResultList();
return Optional.ofNullable(list.get(0));
}
public void save(Cache cache) {
cache = em.find(Cache.class, cache.getId());
em.merge(cache);
}
}
Pastikan mekanisme penguncian ini ada di dalam transaksi karena penguncian akan dilepaskan saat transaksi dilakukan atau dibatalkan.