Salut,
Je réalise actuellement une application web qui utilise les lib suivantes (pour référence) :
- Hibernate (3.5.6)
- Spring (3.0.5)
- JSF (2.1.1-b03)
- MySQL (5.5.10)
- mysql-connector-java (5.1.9)
- c3p0 (0.9.1.2)
Le tout sur un Tomcat 7.0.14
Depuis quelques temps, je me tapais des lock wait timeout, mais jusqu'à présent, j'avais réussi à les contourner. Mais cette fois...
Hier, j'ai découvert quelque chose d'intéressant, ces dead lock n'arrivent que lorsque mon EntityManager est annoté avec PersistenceContextType en Extended. Lorsque celui-ci est en Transaction, plus de problème du tout !!!
Première question : Meuh pourquoi ça change quelque chose sur ce point ???
Du coup au début, je me dis facile, je met l'EntityManager en Transaction et roulez jeunesse ! J'ai donc utilisé OpenEntityManagerInViewFilter pour ne plus avoir de LazyInitializationException. Tout se passe bien coté front (couche de présentation JSF), mais lorsque je tente de modifier une liste lazy coté service : Bim! De nouveau LazyInitizalizationException : pas de proxy ou session fermée.
A savoir que tous mes services sont marqués comme étant Transactionnal.
Deuxième question : Donc normalement, la session ne devrait pas être fermée, non ?
Le dead lock (enfin c'est un lock timeout en fait) apparait lorsque je fais ce genre de modif :
Code:
Pour info, les relations sont définies dans les entités de cette manière :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 //Code dans une transaction (dans un autre service, genre ServiceOnSenFout.java) Car c = new Car(); [....] c = this.carService.create(c); Wheel w = new Wheel(); [.....] w.setCar(c); w = this.wheelService.create(w); //<===== Lock timeout
Car :
Wheel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 @OneToMany(mappedBy="car") private List<Wheel> wheels;
Le truc bizarre, et que je vois MySQL qui semble locker l'enregistrement correspondant à c sur la dernière ligne (celle avec la flèche). Et au bout de 50 secondes qu'il n'a pas réussi à obtenir ce lock, il dégage (c'est le seul verrou qui apparaît dans MySQL).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="ID_CAR") private Car car;
Donc voilà. Honnêtement, je n'en peux plus, je crois que j'ai tout essayé dans tout les sens, et c'est totalement bloquant pour la suite de mon projet. Qui plus est, ce genre de bloquage se retrouve à de nombreux endroits dans l'application... Je dois donc me planter quelque part de façon monumentale, mais où ?
LTourist
Partager