Pages

Thursday, January 29, 2009

Supprimer les EJbs par Spring

J'ai procédé chez mon client à la réalisation d'une étude sur la suppression des EJBs Sessions sur un de leur applicatif java.

Pourquoi supprimer les EJBs Sessions?
  • Pour simplifier l'architecture logicielle de l'applicatif.
  • Pour simplifier la plateforme de développements.
  • Pour simplifier le processus de construction de l'application.
  • Pour augmenter la productivité des développeurs.
  • Pour banaliser l'infrastructure serveur (pas de différenciation serveur métier et serveur présentation).

Qu'apportent les Ejbs Sessions au niveau de l'applicatif?
  • La possibilité de séparer sur des infrastructures différentes la partie présentation et la partie métier. Cette possibilité n'est plus exploitée du fait de leur volonté de banaliser l'infrastructure serveur.
  • La possibilité d'appeler la couche Ejbs ( couche "métier") depuis d'autres applications. Ce choix d'interfaçage n'a pas été retenu et il sera pris en charge par la mise en place de Web Services.
  • La gestion des transactions. C'est la problématique intéressante qui reste à traiter... avec Spring évidemment...

L'intégration de Spring pour prendre en charge la gestion des transactions est réellement facile. Il existe 2 possibilités :
  • de façon déclarative dans le fichier de conf Spring.
  • Par annotation.
Après avoir testé les 2, j'ai choisi de le faire par annotations. L'inconvénient est d'être intrusif en rajoutant les annotations "@Transactional" dans le code. En revanche, cela augmente la lisibilité au niveau du code. Dans tous les cas, je crois qu'il n'y a pas de mauvaises façons de faire avec Spring mais dans tous les cas des façons "simplifiantes". Voici le lien vers la documentation de Spring qui m'a aidé concernant la gestion des transactions.

Dans le cadre du projet concerné, l'environnement de développement se base sur un simple serveur web Tomcat alors qu'en production, c'est un serveur d'application JBoss. L'applicatif à aussi la particularité d'utiliser un ensemble de datasources.

J'utilise alors un transaction manager différent selon l'environnement :
  • Dans l'environnement de développement avec Tomcat, je ne pouvais pas me servir du transactionManager proposer par Spring (org.springframework.jdbc.datasource.DataSourceTransactionManager) car il ne gère qu'une seule source de données. Un article sur le site javaworld explique comment mettre en place un "ChainedTransactionManager" qui s'appuie ensuite sur le transactionManager de spring et permet de gérer plusieurs datasources. Voici un extrait de conf spring correspondante :
     <!-- aop pour la gestion des transactions -->
    <tx:annotation-driven transaction-manager="txManager" />

    <!-- recuperation des datasources en jndi -->
    <jee:jndi-lookup id="datasource1" jndi-name="jdbc/ds1" />
    <jee:jndi-lookup id="datasource2" jndi-name="jdbc/ds2" />
    <jee:jndi-lookup id="datasource3" jndi-name="jdbc/ds3" />
    <jee:jndi-lookup id="datasource4" jndi-name="jdbc/ds4" />

    <!-- declaration du transaction manager -->
    <bean name="txManager" id="txManager" class="com.springsource.open.db.ChainedTransactionManager">
    <property name="transactionManagers">
    <list>
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="datasource1" />
    </bean>
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="datasource2" />
    </bean>
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="datasource3" />
    </bean>
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="datasource4" />
    </bean>
    </list>
    </property>
    </bean>
  • Dans l'environnement de production avec Jboss, pas de soucis, j'utilise le transaction manager JTA de spring (org.springframework.transaction.jta.JtaTransactionManager). Voici l'extrait de la conf Spring correspondante :
     <!-- transaction manager JTA -->
    <bean name="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />


    <!-- aop pour la gestion des transactions -->
    <tx:annotation-driven transaction-manager="txManager" />