Lorsque vous appelez une méthode sans @Transactional
dans un bloc de transaction, la transaction parente continuera avec la nouvelle méthode. Il utilisera la même connexion à partir de la méthode parente (avec @Transactional
) et toute exception provoquée dans la méthode appelée (sans @Transactional
entraîner la restauration de la transaction comme configuré dans la définition de transaction.
Si vous appelez une méthode avec une @Transactional
annotation à partir d'une méthode @Transactional
dans la même instance, le comportement transactionnel des méthodes appelées n'aura aucun impact sur la transaction. Mais si vous appelez une méthode avec une définition de transaction à partir d'une autre méthode avec une définition de transaction, et qu'ils sont dans des instances différentes, le code de la méthode appelée suivra les définitions de transaction données dans la méthode appelée.
Vous pouvez trouver plus de détails dans la section Gestion des transactions déclaratives de la documentation des transactions de printemps .
Le modèle de transaction déclarative Spring utilise le proxy AOP. le proxy AOP est donc responsable de la création des transactions. Le proxy AOP ne sera actif que si les méthodes avec dans l'instance sont appelées depuis l'extérieur de l'instance.
will follow the transaction definitions given in the called method
. Mais si l'appel provient de la même instance d'objet, il n'aura aucun effet puisque l'appel ne se propage pas à travers les proxys aop qui sont responsables de la maintenance de la transaction.@Transactional
définition à partir d'un objet / instance différent, même si la méthode appelante a des@Transactional
attributs différents , la méthode appelée suivra sa propre définition de transaction.Cela dépend d'un niveau de propagation . Voici toutes les valeurs de niveau possibles .
Par exemple, dans le cas où un niveau de propagation est imbriqué, une transaction en cours sera "suspendue" et une nouvelle transaction sera créée ( note: la création réelle d'une transaction imbriquée ne fonctionnera que sur des gestionnaires de transactions spécifiques )
Le niveau de propagation par défaut (ce que vous appelez "comportement") est REQUIS . Dans le cas où une méthode "interne" est appelée avec une
@Transactional
annotation dessus (ou est traitée de manière déclarative via XML), elle s'exécutera dans la même transaction , par exemple "rien de nouveau" n'est créé.la source
@Transactional marque la limite de la transaction (début / fin) mais la transaction elle-même est liée au thread. Une fois qu'une transaction démarre, elle se propage à travers les appels de méthode jusqu'à ce que la méthode d'origine soit renvoyée et que la transaction soit validée / annulée.
Si une autre méthode est appelée avec une annotation @Transactional, la propagation dépend de l'attribut de propagation de cette annotation.
la source
La méthode interne affectera la méthode externe si la méthode interne n'est pas annotée avec @Transactional.
Si la méthode interne est également annotée avec @Transactional avec
REQUIRES_NEW
, ce qui suit se produira.... @Autowired private TestDAO testDAO; @Autowired private SomeBean someBean; @Override @Transactional(propagation=Propagation.REQUIRED) public void outerMethod(User user) { testDAO.insertUser(user); try{ someBean.innerMethod(); } catch(RuntimeException e){ // handle exception } } @Override @Transactional(propagation=Propagation.REQUIRES_NEW) public void innerMethod() { throw new RuntimeException("Rollback this transaction!"); }
La méthode interne est annotée
REQUIRES_NEW
et lève une exception RuntimeException afin qu'elle définisse sa transaction sur rollback mais N'AFFECTERA PAS la transaction externe. La transaction externe est PAUSE lorsque la transaction interne démarre, puis REPREND UNE FOIS la transaction interne terminée. Ils s'exécutent indépendamment l'un de l'autre, de sorte que la transaction externe PEUT s'engager avec succès.la source