Bonjour,
J'utilise depuis très récemment Spring 2.0 et iBatis (avec AppFuse) et il se trouve que j'ai du mal à régler un problème de transaction non prise en compte.
Dans un manager, donc une classe métier gérée par Spring, j'ai besoin de faire un traitement transactionnel, constitué de plusieurs opérations de mise à jour sur une base de données, ainsi qu'au milieu de celles-ci, un dump de ma base (postgres) dans un fichier, à l'aide de l'outil DdlUtils.
En d'autres termes :
- Copie de données, incrémentation d'un compteur dans une table
- Dump des données dans un fichier (au format XML avec l'API DdlUtils mais peu importe)
- Nettoyage suppression des données dumpées...
Il se trouve que mon fichier de dump doit contenir les données qui viennent d'être mises à jour juste avant. Or il s'avère que ce n'est pas le cas car l'outil DdlUtils, à qui ont doit fournir une datasource, effectue son dump, sans considérer la transaction courante. Donc, en fait, DdlUtils, en faisant un dataSource.getConnection(), ne récupère visiblement pas la connexion liée à la Transaction courante. Ainsi, j'obtiens un deadlock qui empèche d'exécuter le reste du traitement toujours sur la même base.
J'ai tenté tout un tas de choses sans succès (TransactionAwareDataSourceProxy, wrapper un DataSource pour avoir la maîtrise de ce qu'il fournit à DdlUtils, modifier la déclaration du service pour que celui-ci soit soumis à mon Transaction manager...etc). J'imagine qu'il faut peut-être parvenir à récupérer la connexion courante sur laquelle la transaction est active mais je n'en suis pas certain et je ne sais comment faire.
Comme mon expérience avec Spring est toute nouvelle et mes recherches ayant été relativement infructueuses, j'apprécierais qu'on m'explique comment aborder ce genre de problématique. Sur quels principes partir et quelles notions à bien avoir en tête.
Je vous remercie par avance.
A titre d'illustration, voici quelques éléments de mon implémentation courante :
Ma Classe service :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public class MyManagerImpl extends BaseManager implements MyManager { ... private DataSourceTransactionManager transactionManager; ... public DataSourceTransactionManager getTransactionManager() { return transactionManager; } public void setTransactionManager(DataSourceTransactionManager transactionManager) { this.transactionManager = transactionManager; } public String synchAndDumpDB(){ while(...) { .... quelques mises à jour / créations dans la bdd ... // Dump de la base ddltutils(transactionManager.getDataSource()) .... d'autres mises à jour / créations dans la bdd } } .... }
applicationContext-ibatis.xml :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
applicationContext-service.xml :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 <bean id="myManager" class="com.myapp.MyManagerImpl"> <property name="transactionManager"> <ref bean="transactionManager"/> </property> .... autres propriétés et déclaration DAO </bean>
Partager