Question Spring @Héritage d'héritage


J'ai un ensemble de @Service les beans qui héritent des fonctionnalités principales d'une classe abstraite. J'ai marqué chacun des services concrets de la sous-classe avec @Service et @Transactional. La super-classe abstraite contient la méthode du point d'entrée public pour chacun de ces services. En d'autres termes, j'ai quelque chose de similaire à ce qui suit:

abstract class AbstractService {

    public void process() {
        // Do common initialisation code here
        processSpecific();
        // Do common completion code here
    }

    abstract protected void processSpecific();
}


@Service @Transactional
public class FirstSpecificService extends AbstractService {
    protected void processSpecific() {
        // Do specific processing code here
    }
}


@Service @Transactional
public class SecondSpecificService extends AbstractService {
    protected void processSpecific() {
        // Do different specific processing code here
    }
}

Le code spécifique de chaque service de sous-classe concret appelle plusieurs fois la couche DAO pour apporter des modifications à la base de données. REQUIRED comme type de propagation transactionnel.

Maintenant, avec les services définis ci-dessus, j'ai découvert qu'il n'existait aucune transaction en cours dans le code de ces services de sous-classe concrets et que chaque appel à la couche DAO créait une nouvelle transaction, effectuant les modifications et validant la transaction. revenir.

Cependant, si j'annote la super-classe abstraite avec @Transactional, alors une transaction est créé correctement, et les sous-appels à la couche DAO participent tous à la transaction en cours.

Donc, ma question est, quelles sont les règles pour hériter de la @Transactional comportement? Pourquoi Spring n'utilise pas le @Transactional sur les services concrets de sous-classe qu'il instancie réellement? Est-ce que le @Transactional doivent être sur la super-classe dans ce cas parce que c'est là que la méthode de point d'entrée publique est?


14
2018-03-29 03:10


origine


Réponses:


De la documentation de transaction du printemps,

Remarque: en mode proxy (par défaut), seule la méthode «externe»   les appels entrants via le proxy seront interceptés. Cela signifie que   "auto-invocation", c'est-à-dire une méthode dans l'objet cible appelant   autre méthode de l'objet cible, ne conduira pas à une transaction réelle   à l'exécution même si la méthode invoquée est marquée par @Transactional!

Bien que vous ayez le @Transactional sur votre implémentation concrète et que vous appelez la méthode de processus qui est réellement transactionnelle par votre annotation, la méthode de processus appelant processSpecific sur votre sous-classe n'est pas transactionnelle en raison de cet appel interne.

Regardez dans le tissage.


9
2018-03-29 05:46



Avez-vous lu la partie sur la propagation des transactions et comment il peut être configuré en utilisant @Transactional?

Un autre domaine d’intérêt est que Spring vous recommande de annoter des classes de béton (comme s'oppose à annoter les interfaces).


1
2018-03-29 05:45