L'annotation est implémentée avec un proxy, donc elle ne s'applique que si l'appel passe par le bean depuis l'extérieur. Un appel depuis une autre méthode de la même classe contourne totalement le proxy, et c'est la cause la plus fréquente. Autres raisons : la méthode n'est pas publique, l'exception levée est checked et ne déclenche donc pas de rollback par défaut, le bean a été créé hors du conteneur, ou il fallait une nouvelle transaction et la propagation est restée à required.
Pourquoi les recruteurs posent cette question
C'est une question Spring pratique avec plusieurs bonnes réponses, donc elle révèle à la fois la profondeur et l'expérience réelle du débogage. Le recruteur veut que l'auto-invocation à travers le proxy soit nommée en premier, plus la règle de rollback sur les exceptions checked, qui surprend. Les relances passent souvent à la propagation, à ce qui a sa place dans une transaction, et au danger des longues transactions qui retiennent une connexion.
Comment structurer votre réponse
- Commencez par le modèle de proxy, puisqu'il explique la plupart des échecs.
- Couvrez l'auto-invocation et les exigences de visibilité.
- Énoncez la règle de rollback par défaut et comment la changer.
- Ajoutez ce qui ne devrait pas du tout se trouver dans une transaction.
Exemple de réponse
Neuf fois sur dix c'est de l'auto-invocation. Spring enveloppe le bean dans un proxy, et la transaction démarre quand un appelant passe par ce proxy, donc si une méthode publique de la même classe appelle directement la méthode annotée, l'appel ne sort jamais de l'objet et aucune transaction ne commence. Le correctif est de déplacer la méthode dans un autre bean ou d'injecter le bean dans lui-même, et le vrai correctif est en général que la frontière était de toute façon au mauvais endroit. Ensuite je vérifie les bases : la méthode doit être publique, le bean doit être géré par Spring et non créé avec new, et la règle de rollback piège les gens parce que par défaut elle ne fait un rollback que sur les exceptions unchecked, donc une exception checked laisse commiter à moins que je précise rollbackFor. Je regarde aussi la propagation, puisqu'un traitement qui doit survivre au rollback de l'appelant a besoin de requires new, ce qui prend une deuxième connexion, et ça compte si le pool est petit. Et je garde les transactions courtes : pas d'appels HTTP, pas de publication de messages, pas d'attente sur quoi que ce soit dedans, parce que retenir une connexion à la base pendant qu'on appelle un tiers, c'est comme ça qu'un pool s'épuise.
Vous passez cet entretien bientôt ? GhostPilot écoute votre appel en direct, repère la question dès qu'elle est posée et affiche une réponse structurée à l'écran en temps réel. Essayez-le lors de votre prochain entretien blanc, ou prenez un Session Pass à $29, sans abonnement, pour le jour J.
Voir comment ça marcheQuestions de relance à prévoir
- Que fait réellement la propagation requires new au pool de connexions ?
- Pourquoi attraper une exception dans une transaction peut-il quand même provoquer un rollback ?
- Comment publieriez-vous un événement uniquement après le commit de la transaction ?
Autres questions pour Développeur Java
Votre recruteur posera sa propre version de celle-ci. Collez votre véritable fiche de poste dans le Question Predictor gratuit et obtenez les 20 questions que ce poste a le plus de chances de poser, avec ce que chacune cherche vraiment à sonder.
Prédire mes questions