Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1255 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  [JTA] "Sous-transaction" depuis une Servlet ...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[JTA] "Sous-transaction" depuis une Servlet ...

n°626861
Ygrec
Posté le 31-01-2004 à 11:55:35  profilanswer
 

Bonjour à tous,
 
J'aimerais vous soumettre un problème qui me pollue l'existence depuis 1 semaine  :fou:  
En synthèse, j'aimerais pouvoir démarrer une sous-transaction JDBC dans une transaction JTA (locale ou globale ça importe peu), afin de commiter seulement une "partie" de mes appels au SGBD, et ceci depuis une servlet. Et surtout sans passer par un EJB (cf attributs required_new sur les méthodes qui me permettraient de faire ça facilement ...)
Un exemple simple de ce que ça permettrait de faire est de logger en base des états "success" ou "failure" de partie de processus qui font des insert, update ou delete dans la base...
Suis-je vraiment clair ? ...  :heink:  
Sur un exemple, ça donnerait quelque chose comme ça :
Dans la servlet appelante :

Code :
  1. try {
  2.     UserTransaction ut = ...
  3.     ut.begin();
  4.     MyProcess mp = new MyProcess();
  5.     mp.step1();
  6.     }
  7. catch (Exception e) {
  8.     {
  9.     ut.setRollbackOnly();
  10.     }
  11. finally
  12.     {
  13.     try { ut.commit(); } catch (..) {...}
  14.     }


 
Avec dans la classe MyProcess :

Code :
  1. void step1(ut);
  2. {
  3.    Connection con = getConnection();
  4.    try {
  5.        // Insertion de données  
  6.        "INSERT INTO T ...
  7.        // D'autres choses qui pourraient lever une exception ...
  8.        ...
  9.        // Log de l'état "ok" du processus
  10.        log("step1", "success" );
  11.        }
  12.     catch (Exception e) {
  13.        log("step1", "failure" );
  14.        throw e;
  15.        }
  16.     finally
  17.        {
  18.        // Fermeture connection, etc...
  19.        }
  20. }
  21. void log(String step, String status)
  22. {
  23.    Connection con = getConnection();
  24.    try {
  25.        // Insertion du status pour le step ...
  26.        "INSERT INTO STATUS (STEP, STATUS) values (?, ?)
  27.        }
  28.     catch (Exception e) {
  29.        // etc ...
  30.        }
  31.     finally
  32.        {
  33.        // Fermeture connection, etc ...
  34.        }
  35. }


 
Cet exemple est un cas d'école, n'est-ce pas ?  :D  
Il pourrait être "résolu" facilement en stockant les messages "loggés" dans une quelconque variable, et en effectuant les insertions en base à la fin de l'exécution de la servlet (donc après le ut.commit()). Mon problème réel est plus générique que ça, et même si j'ai indiqué au début que je ne *voulais* pas utiliser d'EJB, les fonctions dont je parle doivent être utilisables dans n'importe quel contexte (y compris dans ce cas d'EJB...) et sans demander de réécriture de code, ou adaptation du code existant. En gros, ce dont j'ai besoin, c'est d'un OutputStream sur JDBC ;-) (Pas taper, je sais que j'écris une horreur ....)
 
J'ai déjà exploré les pistes suivantes :
1) Utiliser une autre dataSource : pas de chance, elle est incluse d'office dans la transaction JTA démarrée ...
2) Obtenir la connection depuis le DriverManager, et faire un commit JDBC : idem, j'ai une exception qui m'indique que je ne peux pas commiter une transaction JDBC dans une transaction JTA... Normal ...
3) Jouer avec les méthodes susped, begin, etc... et resume du TransactionManager : Déjà c'est pas "standard" (merci Hibernate  :) pour le moyen d'avoir une instance de TransactionManager). Ensuite, même si ça fonctionne sur mon poste de dév (WSAD, MySQL ou Cloudscape) ou un Websphere sur NT, ben ça m'explose férocement à la figure si j'esssaye ça sur ma plate-forme de prod (WS 4 sur un Mainframe sous z/OS) avec des "SecurityException" ... Donc pas moyen d'utiliser cette méthode non plus ...
4) Utiliser un Thread spécifique lancé à partir d'une servlet d'init qui ferait les accès BD (je sais, je sais ... "Normalement" c'est interdit de faire de nouveaux Threads à la main, mais bon ...) : marche pô non plus, cf impossible d'avoir une Connection sur le Mf à partir d'un Thread "anonyme", toujours à cause de JAAS ...
 
Là je craque ...
J'ai été regarder log4j et les différentes versions de JDBCAppender (histoire de voir ce qu'ils avaient fait), mais aucune ne prend ce problème en compte (et donc il peut y avoir des "rollbacks" de logs, ce qui est quand même un comble ...). Je dirai même plus (...) : personne ne semble avoir "détecté" ce problème ... ?
Heelp please ... Est-ce que j'essaye de faire un truc *vraiment* impossible ... ??  :pt1cable:  
Merci d'avoir lu jusque là en tout cas ! :D  
 

mood
Publicité
Posté le 31-01-2004 à 11:55:35  profilanswer
 

n°626885
darklord
You're welcome
Posté le 31-01-2004 à 12:42:47  profilanswer
 

bin session bean et requiresnew. Si tu bosses avec JTA, t'as pas 36 solutions hein. Si tu ne peux pas utiliser de SB, bin je vois mal comment tu peux t'en sortir

n°626898
benou
Posté le 31-01-2004 à 13:01:20  profilanswer
 

DarkLord a écrit :

bin je vois mal comment tu peux t'en sortir


en faisant ce que fait le conteneur ejb avec les sb


---------------
ma vie, mon oeuvre - HomePlayer
n°626902
Ygrec
Posté le 31-01-2004 à 13:03:15  profilanswer
 

Merci de ta réponse DarkLord.
Après avoir exploré ttes les pistes que j'ai donné en haut, j'en étais à la même conclusion ... mais on a tjrs un peu d'espoir d'avoir raté quelque chose nan ? :)
Maintenant, je trouve qu'il manque qque chose de "standard" dans l'API JTA pour pouvoir faire l'équivalent d'un SB/Requiresnew depuis un container Web sans passer par un EJB ... Y'a tout ce qu'il faut (cf TransactionManager) mais c'est "réservé" au container EJB ...

n°626905
Ygrec
Posté le 31-01-2004 à 13:07:58  profilanswer
 

Benou,
 
Je suis d'accord avec toi, c'est d'ailleurs ce que j'ai essayé de faire mais malheureusement ça ne colle pas avec mon env de prod.
En gros le truc c'est :
 

Code :
  1. TransactionManager txMgr = getTxManager(); // Là ça dépend du serveur ...
  2. // On récupère la transaction courante
  3. Transaction currentTx = txMgr.suspend();
  4. // On en démarre une nouvelle
  5. txMgr.begin();
  6. // On peut faire des accès aux ressources
  7. // Commit de la nouvelle tx
  8. txMgr.commit();
  9. // Et restore de l'ancienne
  10. txMgr.resume(currentTx);


 
Le pb comme je l'ai dit plus haut c'est que sur WS z/OS j'ai une SecurityException sur le commit ...

n°626922
benou
Posté le 31-01-2004 à 13:46:02  profilanswer
 

désolé, je vais pas pouvoir t'aider : je connais pas JTA :/


---------------
ma vie, mon oeuvre - HomePlayer
n°626934
Ygrec
Posté le 31-01-2004 à 14:14:07  profilanswer
 

Benou,
 
Juste pour info, je peux te dire que ce n'est pas sorcier et que si tu codes des SB, EB & co ben tu l'utilises sans le savoir (mode donneur de leçons off of course hein ! :ange: ).  
Y'a 2 trucs à connaitre en fait pour l'utiliser explicitement :
1) Depuis une servlet :  
 UserTransaction ut = (UserTransaction)context.lookup("java:comp/UserTransaction" );
2) Depuis un SB BMP :
 UserTransaction = getContext().getUserTransaction();
Ensuite ut.begin(), ut.commit(), ut.rollback() ou ut.setRollbackOnly().
Bon d'accord... Y'a aussi des subtilités quand tu combines des ressources XA et pas XA, mais en général y'a un architecte qui est passé avant toi pour vérifier que les ressources se coordonnaient correctement ...
Le problème (et c'est pour ça que j'ai parlé de "lacune" dans cette API) c'est qu'elle est partiellement masquée, cf l'interface TransactionManager et le fait qu'il n'y a pas de "méthode" pour récupérer le TransactionManager courant... Si tu as l'occasion, va jeter un oeil au code du projet Hibernate (cf ci-dessus), c'est affligeant de voir comment tout ça peut dériver en choses "non standards" parce que la norme n'est pas assez précise ou complète sur le sujet ...
M'enfin ... Je ne me sens pas trop le courage d'aller poster un truc chez Sun pour leur demander de faire le nécessaire :D . Y z'ont certainement eu une bonne raison pour avoir limité son usage !
 
Au final, je vais logger dans un fichier moua :D
Merci d'avoir pris du temps pour me répondre en tout cas !

n°627564
darklord
You're welcome
Posté le 01-02-2004 à 10:32:40  profilanswer
 

benou a écrit :


en faisant ce que fait le conteneur ejb avec les sb


 
[:kiki] tu me prends pour un con ou quoi?

n°627566
darklord
You're welcome
Posté le 01-02-2004 à 10:33:45  profilanswer
 

Ygrec a écrit :

Benou,
 
Juste pour info, je peux te dire que ce n'est pas sorcier et que si tu codes des SB, EB & co ben tu l'utilises sans le savoir (mode donneur de leçons off of course hein ! :ange: ).  
Y'a 2 trucs à connaitre en fait pour l'utiliser explicitement :
1) Depuis une servlet :  
 UserTransaction ut = (UserTransaction)context.lookup("java:comp/UserTransaction" );
2) Depuis un SB BMP :
 UserTransaction = getContext().getUserTransaction();
Ensuite ut.begin(), ut.commit(), ut.rollback() ou ut.setRollbackOnly().
Bon d'accord... Y'a aussi des subtilités quand tu combines des ressources XA et pas XA, mais en général y'a un architecte qui est passé avant toi pour vérifier que les ressources se coordonnaient correctement ...
Le problème (et c'est pour ça que j'ai parlé de "lacune" dans cette API) c'est qu'elle est partiellement masquée, cf l'interface TransactionManager et le fait qu'il n'y a pas de "méthode" pour récupérer le TransactionManager courant... Si tu as l'occasion, va jeter un oeil au code du projet Hibernate (cf ci-dessus), c'est affligeant de voir comment tout ça peut dériver en choses "non standards" parce que la norme n'est pas assez précise ou complète sur le sujet ...
M'enfin ... Je ne me sens pas trop le courage d'aller poster un truc chez Sun pour leur demander de faire le nécessaire :D . Y z'ont certainement eu une bonne raison pour avoir limité son usage !
 
Au final, je vais logger dans un fichier moua :D
Merci d'avoir pris du temps pour me répondre en tout cas !


 
:jap:
 
et je ne connaissais pas le coup du UserTransaction ut = (UserTransaction)context.lookup("java:comp/UserTransaction" ); (faut dire que je suis nul en servlet/JSP aussi)

n°627579
benou
Posté le 01-02-2004 à 11:00:04  profilanswer
 

DarkLord a écrit :


[:kiki] tu me prends pour un con ou quoi?


mais nan :o
 

DarkLord a écrit :


et je ne connaissais pas le coup du UserTransaction ut = (UserTransaction)context.lookup("java:comp/UserTransaction" ); (faut dire que je suis nul en servlet/JSP aussi)


rien à voir avec les servlets [:kiki]
 

DarkLord a écrit :


[:kiki] tu me prends pour un con ou quoi?


bha du coup oui un peu [:joce]


---------------
ma vie, mon oeuvre - HomePlayer
mood
Publicité
Posté le 01-02-2004 à 11:00:04  profilanswer
 

n°627583
Ygrec
Posté le 01-02-2004 à 11:09:18  profilanswer
 

Citation :


UserTransaction ut = (UserTransaction)context.lookup("java:comp/UserTransaction" );  
 
rien à voir avec les servlets [:kiki]


 
Euh ...  
Sans vouloir polémiquer  :ange: je suis d'accord, parce que c'est plutôt une API JTA ...  
Edit : en fait non ... Mais c'est le moyen de récupérer une UT depuis le contexte JNDI
Mais je ne connais pas d'autre endroit où on l'utilise comme ça ?  
Benou > y'en a d'autres ??


Message édité par Ygrec le 01-02-2004 à 11:10:55
n°627594
benou
Posté le 01-02-2004 à 11:28:57  profilanswer
 

Ygrec a écrit :

[quote]
Benou > y'en a d'autres ??


j'en sais rien, en tout cas, le lookup a rien à voir avec l'API servlet [:spamafote]


---------------
ma vie, mon oeuvre - HomePlayer
n°627644
darklord
You're welcome
Posté le 01-02-2004 à 12:48:45  profilanswer
 

benou a écrit :


j'en sais rien, en tout cas, le lookup a rien à voir avec l'API servlet [:spamafote]


 
mais j'ai jamais dit ca.
 
dans un container EJB tu as accès à ta transaction via le SessionContext. Et donc comme je n'ai jamais eu à utiliser je jndi.lookup(...) je ne connaissais pas.
 
maintenant j'en déduis qu'on utilise ce genre de choses princialement en servlet puisque pour tout ce qui est EJB on y accède autrement d'où mon "(faut dire que je suis nul en servlet/JSP aussi)".
 
Et donc réflexion faite, benou, tu me prends *vraiment* pour un con.


Message édité par darklord le 01-02-2004 à 12:53:40
n°627825
benou
Posté le 01-02-2004 à 18:07:18  profilanswer
 

DarkLord a écrit :


Et donc réflexion faite, benou, tu me prends *vraiment* pour un con.


t'as fini oui :o
 
 
perso, en servlet, je ne me suis jamais servi de JNDI ... Tomcat le fait un peu, mais généralement les moteurs de servlets simples (pas un websphere ou un weblogic quoi) ne fournissent pas grand chose comme composant => je les instancie moi-même et les range dans le ServletContext ... y a pas vraiment besoin de plus ...


---------------
ma vie, mon oeuvre - HomePlayer

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  [JTA] "Sous-transaction" depuis une Servlet ...

 

Sujets relatifs
Attendre un évènement en base de données dans une servletservlet, afficher sur plusieurs pages le recordset
Quelqu'un a appele ma Servlet?[Postgresql] Transaction : équivalent à @@error en sql server ?
[Servlet] Envoyer un flux à une servletInformatique distribuée : pb de parallèlisme dans une transaction
[Java]Connection à un site via une servlet[Servlet][Tomcat] Ressource indisponible
Imbriquer 2 transaction[TOMCAT] Déclencher l'appel de la méthod init d'une servlet. [RESOLU]
Plus de sujets relatifs à : [JTA] "Sous-transaction" depuis une Servlet ...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR