Spring Boot : écrire le serveur (école d'ingénieur) · Chapitre 6 · Exercice de TD
Garder une trace même en cas d'échec
Relations et transactions · niveau 3 (difficile)
Énoncé
Le libraire veut noter chaque tentative de commande (l'adresse du client), même refusée. Écrire une entité Tentative, un service Journal et un service qui note la tentative puis passe la commande. Pourquoi une simple méthode @Transactional ne suffit-elle pas pour Journal.noter ? Quelle propagation utiliser ?
Corrigé
Si noter participait à la transaction de la commande, la trace serait annulée avec elle en cas de refus : c'est précisément le cas à noter. Il faut une transaction séparée, validée tout de suite :
@Service
public class Journal {
private final TentativeDepot tentatives;
public Journal(TentativeDepot tentatives) {
this.tentatives = tentatives;
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void noter(String courriel) {
tentatives.save(new Tentative(courriel));
}
}
REQUIRES_NEW suspend la transaction de l'appelant, en ouvre une nouvelle, la valide, puis reprend la première. Le service qui l'utilise doit être un autre bean (sinon l'appel interne ignorerait l'annotation) :
@Transactional
public CommandeConfirmee passer(CommandeDemande demande) {
journal.noter(demande.courriel()); // un AUTRE bean : l'annotation est bien appliquée
return commandes.commander(demande);
}
Le test passe une commande refusée (4 exemplaires d'un livre qui en a 3) : l'exception remonte, aucune commande n'est enregistrée, et la tentative l'est.
100 % gratuit
La suite du chapitre est sur Adloun
- 9 autres exercices corrigés dans ce chapitre
- Les 2 QCM du chapitre, le premier sans compte
- Le tuteur, qui guide pas à pas sans donner la réponse
Sans compte : le cours et le premier QCM. Exercices et tuteur : inscription gratuite en 30 secondes, sans carte bancaire.