Selon votre mappage, la séquence d'opérations devrait ressembler à ceci :
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);
Une mise à jour ou un supprimer signifie acquérir un verrou exclusif , même sur READ_COMMITTED
niveau d'isolement.
Si une autre transaction souhaite mettre à jour la même ligne avec la transaction en cours d'exécution (qui a déjà verrouillé cette ligne en question), vous n'obtiendrez pas de blocage, mais un délai d'acquisition de verrou exception.
Puisque vous avez un blocage, cela signifie que vous acquérez des verrous sur plusieurs tables et que les acquisitions de verrous ne sont pas correctement ordonnées.
Assurez-vous donc que les méthodes de la couche de service définissent les limites de la transaction, et non les méthodes DAO. Je vois que vous avez déclaré le get et trouver méthodes à utiliser SUPPORTED, ce qui signifie qu'elles n'utiliseront une transaction que si une est en cours de démarrage. Je pense que vous devriez également utiliser REQUIRED pour ceux-ci, mais marquez-les simplement comme read-only = true
.
Assurez-vous donc que l'aspect transactionnel applique la limite de transaction sur la "mymethod" et non sur les DAO.