Ok, je me suis un peu plongé dans la spec EJB 3.1, et je vois que pour les méthodes non-transactionnelles la syntaxe est :.
Code : Sélectionner tout - Visualiser dans une fenêtre à part @TransactionAttribute(NOT_SUPPORTED)
Je pense qu'on est tous d'accord pour dire que le comportement par défaut doit être redéfinissable au cas par cas via des annotations. C'est ce que font les EJB3.1 et Spring, pas d'élément différentiateur là-dessus.
En revanche, pour te répondre OButterlin, on sera toujours au moins obligés de se reposer un peu sur le comportement par défaut, à moins de redéfinir pour chaque méthode transactionnelle :
- le niveau d'isolation
- la propagation
- le timeout
- readOnly ou pas
- ...
Donc 2 possibilités:
- Soit on est d'accord avec le comportement par défaut des EJBs qui est d'ouvrir une transaction en écriture pour chaque méthode y compris pour les méthodes find, get etc (Alexis, STP corrige moi si je me trompe).
- Soit il va y avoir un peu de configuration à écrire, et c'est là que Spring apporte un outillage intéressant.
Par exemple, les annotations héritées:
et par la suite, je peux annoter mes méthodes comme suit:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 @Transactional(readOnly="true",propagation=PROPAGATION.REQUIRED, timeout="20") public @interface ReadOnlyTransactional { }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 @ReadOnlyTransactional public Client findClient(...) { }
J'aurais également pu aller plus loin et regrouper un ensemble d'annotations que j'utilise beaucoup comme suit:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 @Transactional(...) @RolesAllowed("ROLE_MEMBER") public @interface ReadOnlyServiceMethod { }
Encore une fois, ça c'est pour le cas où l'on souhaite placer des annotations dans le code. Nous avons aussi beaucoup de clients qui ont fait le choix de gérer la politique transactionnelle de leurs applis de manière générique par configuration xml comme suit:
Si vous souhaitez mettre en place ce type de gestion globale, il me semble bien que le seul moyen est d'utiliser Spring.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 <aop:pointcut id=txMethods expression=execution(public * com.springsource..*Service.*(..))/> <tx:advice id=txAdvice> <tx:attributes> <tx:method name="find*" read-only="true"/> <tx:method name="update*"/> </tx:attributes> </tx:advice>
Il y a aussi un 3è cas intéressant: par défaut, la mise en place des transactions nécessite un surcoût au démarrage de l'application. C'est le cas pour les EJB 3.1 comme pour Spring. Chez certains de nos gros clients, sur de très grosses applications, il peut arriver que le temps de démarrage en patisse. Avec Spring (et AspectJ), on peut passer très facilement à un enrichissement du bytecode en phase de compilation. Ca veut dire que ça compile un poil plus lentement, par contre ça démarre plus vite.
Encore une fois, je suis très heureux que nous ayons maintenant un standard de qualité. Mais il est important de comprendre que le choix Spring vs Java EE n'est pas seulement une question de philosophie. Il y a des différences techniques importantes.
Partager