Menurut pemetaan Anda, urutan operasi akan terlihat seperti ini:
Person p = DAO.findPerson(id);
Car car = new Car();
car.setPerson(p);
DAO.saveOrUpdate(car);
p.getCars().add(car);
Car firstCar = p.getCars().get(0);
firstCar.setPerson(null);
p.getCars().remove(firstCar);
if (p.officialCar.equals(firstCar)) {
p.officialCar = null;
p.officialCar.person = null;
}
DAO.delete(firstCar);
Sebuah pembaruan atau hapus berarti mendapatkan kunci eksklusif , bahkan di READ_COMMITTED
tingkat isolasi.
Jika transaksi lain ingin memperbarui baris yang sama dengan transaksi yang sedang berjalan (yang telah mengunci baris yang dimaksud), Anda tidak akan mendapatkan kebuntuan, tetapi batas waktu akuisisi kunci pengecualian.
Karena Anda mengalami kebuntuan, itu berarti Anda memperoleh kunci di beberapa tabel dan akuisisi kunci tidak diatur dengan benar.
Jadi, pastikan bahwa metode lapisan layanan menetapkan batas transaksi, bukan metode DAO. Saya melihat Anda mendeklarasikan mendapatkan dan temukan metode untuk menggunakan DIDUKUNG, artinya mereka akan menggunakan transaksi hanya jika transaksi sedang dimulai. Saya pikir Anda harus menggunakan REQUIRED untuk itu juga, tetapi cukup tandai sebagai read-only = true
.
Jadi pastikan aspek transaksi menerapkan batas transaksi pada "metode saya" dan bukan pada yang DAO.