Printemps - @Transactional - Ce qui se passe en arrière-plan?
Je veux savoir ce qui se passe réellement lorsque vous annotez une méthode avec @Transactional
?
Bien sûr, je sais que le Printemps va envelopper cette méthode dans une Transaction.
Mais, j'ai le texte suivant doutes:
- J'ai entendu dire que le Printemps crée un classe proxy? Quelqu'un peut-il expliquer cela plus en profondeur. Ce fait réside dans le fait qu'classe proxy? Ce qui se passe à la classe réelle? Et comment puis-je voir le Printemps est créé en proxy classe
- J'ai également lu dans le Printemps docs que:
Remarque: ce mécanisme est basé sur les procurations, seulement "externes" méthode des appels arrivant par la procuration seront interceptés. Cela signifie que 'auto-invocation", c'est à dire une méthode de l'objet cible de l'appel à une autre méthode de l'objet cible, ne vous conduira pas à une transaction au moment de l'exécution, même si la méthode invoquée est marqué avec
@Transactional
!
Source: http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html
Pourquoi seulement à l'extérieur de la méthode des appels en vertu de la Transaction et non pas de l'auto-invocation de méthodes?
- De discussion est ici: stackoverflow.com/questions/3120143/...
Vous devez vous connecter pour publier un commentaire.
C'est un grand sujet. Le Printemps de référence doc consacre plusieurs chapitres à elle. Je vous recommande la lecture à ceux Aspect-Oriented Programming et Les Transactions, alors que le Printemps déclaratif de soutien à la transaction, les utilisations de l'AOP à sa fondation.
Mais à un niveau très élevé, le Printemps crée des procurations pour les classes qui déclarent @Transactional sur la classe elle-même ou sur les membres. Le proxy est la plupart du temps invisible au moment de l'exécution. Il fournit un moyen pour le Printemps, pour injecter des comportements avant, après ou autour des appels de méthode dans l'objet proxy. La gestion des transactions est qu'un exemple des problèmes qui peut être accroché dans. Les contrôles de sécurité sont une autre. Et vous pouvez fournir votre propre, trop, pour des choses comme l'exploitation forestière. Ainsi, lorsque vous annotez une méthode avec @Transactional, le Printemps crée dynamiquement un proxy qui implémente la même interface(s) comme la classe que vous soyez à l'annotation. Et lorsque les clients de faire des appels dans votre objet, les appels sont interceptés et les comportements injectés via le proxy mécanisme.
Transactions dans EJB fonctionnent de la même façon, par la manière.
Que vous avez observé, à travers le mécanisme de proxy ne fonctionne que lorsque les appels viennent de certains objet externe. Lorsque vous effectuez un appel interne au sein de l'objet, vous êtes vraiment faire un appel par le biais de la "ce" de référence, qui contourne le proxy. Il y a des façons de contourner ce problème, cependant. J'explique une approche ce post sur le forum dans lequel j'utilise un BeanFactoryPostProcessor injecter une instance du proxy dans "l'auto-référencement des classes" au moment de l'exécution. J'ai enregistrer cette référence à une variable de membre appelé "moi". Alors si j'ai besoin de faire des appels internes qui exigent un changement dans le statut de la transaction du fil, j'ai direct de l'appel à travers le proxy (par exemple, "moi.someMethod()".) Le post sur le forum qui explique plus en détail. Notez que le BeanFactoryPostProcessor code sera un peu différent maintenant, comme il a été écrit au Printemps dernier 1.x calendrier. Mais nous espérons que cela vous donne une idée. J'ai une version mise à jour que je pourrais probablement me rendre disponible.
@Transactional
aussi fermer une session ouverte avecsessionFactory.getCurrentSession()
@Transactional
et@PreAuthorize
(pour les contrôles de sécurité) les annotations, Ne ressort créer des listes de proxy ou de créer une seule procuration avec tous les transversales de la logique?BeanFactoryPostProcessor
. Cependant, il est (à mon avis) très similaire méthode décrite dans cette réponse: stackoverflow.com/a/11277899/3667003 ...et d'autres solutions dans l'ensemble du fil ainsi.Quand le Printemps des charges de votre bean définitions, et a été configurée pour rechercher @Transactional annotations, il va créer ces objets proxy autour de votre bean. Ces proxy objets sont des instances de classes qui sont générés automatiquement lors de l'exécution. Le comportement par défaut de ces objets proxy lorsqu'une méthode est appelée, c'est juste pour invoquer la même méthode sur la "cible" de la fève (c'est à dire votre bean).
Cependant, les procurations peuvent également être fournis avec des intercepteurs, et lorsqu'ils sont présents ces intercepteurs sera invoquée par le proxy avant d'appeler votre cible bean méthode. Pour la cible des haricots annotée avec @Transactional, le Printemps sera de créer un TransactionInterceptor, et de le transmettre au proxy généré objet. Ainsi, lorsque vous appelez la méthode à partir de code client, vous êtes l'appel de la méthode sur l'objet proxy, qui invoque le TransactionInterceptor (qui commence une transaction), qui à son tour appelle la méthode sur votre cible bean. Quand l'appel se termine, le TransactionInterceptor s'engage/annule la transaction. C'est transparent pour le client de code.
Comme pour la "méthode externe" chose, si votre bean invoque l'une de ses propres méthodes, alors il ne sera pas le faire via le proxy. Rappelez-vous, le Printemps enveloppe votre bean dans le proxy, votre bean a aucune connaissance. Seuls les appels de "l'extérieur" de votre bean passer par le proxy.
T-il m'aider?
Comme une personne visuelle, je tiens à peser avec un diagramme de séquence du modèle de proxy. Si vous ne savez pas comment lire les flèches, j'ai lu le premier comme ceci:
Client
exécuteProxy.method()
.exécuté après le retour de la méthode et/ou si la méthode renvoie un
exception
(J'ai été autorisé à poster la photo sur la condition que je l'ai mentionné ses origines. Auteur: Noel Vaes, site web: http://www.noelvaes.eu)
La réponse la plus simple est, sur la méthode que vous avez declare @Transactional la limite de transaction démarre frontière et se termine lorsque la méthode est terminée.
Si vous êtes en utilisant JPA appel, puis tous les commits sont dans cette opération de délimitation. Disons que vous êtes économiser de l'entité1, entity2 et entity3. Maintenant, tout en économisant de entity3 une exception se produisent, alors que enitiy1 et entity2 vient dans la même transaction afin de l'entité1 et entity2 sera restauration avec entity3.
Transaction : (de l'entité1.enregistrer, entity2.enregistrer, entity3.enregistrer). Toute exception entraînera l'annulation de tous JPA transactions avec DB. Interne de la JPA transaction sont utilisés d'ici le Printemps.