Adloun

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

Exercice suivant et tuteur

Sans compte : le cours et le premier QCM. Exercices et tuteur : inscription gratuite en 30 secondes, sans carte bancaire.

Le cours du chapitre · Tous les exercices du chapitre

Exercice suivant et tuteur →