gestion de transaction [RESOLU]

cancel
Showing results for 
Search instead for 
Did you mean: 
fmarin
Member II

gestion de transaction [RESOLU]

bonjour

je suis en train d'approfondir les mécanismes de gestion de transaction.

J'utilise alfresco 4.2.c

J'ai une classe java (javaBacked script) qui contient le code :
      
…/…
TransactionService transactionService = serviceRegistry.getTransactionService();
trx = serviceRegistry.getTransactionService().getUserTransaction();
   try
   {
      trx.begin();
      if (debug) System.out.println("-transaction commence");
      bp=baseParam.traitParam(req);
      if (debug) System.out.println("-transaction finit");
      trx.commit();
   }
   catch(Throwable e)
   {
      try
      {
      trx.rollback();
      System.out.println("rollback sur baseParam.traitParam(req))");
      System.out.println("EXCEPTION : "+e);
      e.printStackTrace();
      }
      catch(Throwable ee)
      {
         System.out.println("erreur de rollback sur baseParam.traitParam(req))");
         System.out.println("EXCEPTION : "+ee);
         ee.printStackTrace();
      }
      bp=true;
   }      
…/…    


baseParam.traitParam(req) me sert à créer le contexte de démarrage (création d'espace et de catégories).

Quand la suite du code ne provoque pas d'exception, tout cela fonctionne parfaitement (j'ai bien mon contexte initialisé).

Quand je provoque une exception dans la suite du code, un rollback général se produit (… et mon contexte n'est plus créé).

Est ce la bonne méthode ?

merci pour votre aide

Frédéric Marin
7 Replies
rguinot
Customer

Re: gestion de transaction [RESOLU]

Que cherchez vous à faire exactement ? vous ne semblez pas interagir avec des données de l'entrepôt à l'intérieur des limites de votre transaction….
Dans tous les cas Ce n'est pas recommandé gérer les transactions manuellement. Il faut utiliser le retryingTransactionHelper qui gère le rejeu des transactions pour vous suite à une liste d'exceptions prédéfinies. cf http://wiki.alfresco.com/wiki/Java_Foundation_API#Using_RetryingTransactionHelper
fmarin
Member II

Re: gestion de transaction [RESOLU]

Bonjour

je me suis bien appuyé sur cette page, mais en me concentrant sur "Handling UserTransaction Directly".

J'ai un premier traitement (initialisation de contexte)qui me permet de créer un "folder" s'il n'existe pas, ainsi que les racines dont j'ai besoin en matière de catégorie (illustré par appel de la méthode traitParam de l'objet baseParam).

J'ai ensuite une recherche Lucene qui me fournit les documents candidats au traitement suivant.

j'ai enfin une itération sur un traitement plus complexe qui explore les propriétés pour chaque node, les soumets à une classe cliente d'un web-service, récupère les résultats, crée un node cible en l'enrichissant des résultats du web service et en le liant à certaines catégories selon ces résultats, et modifie le node source pour ne plus le déclarer comme "candidat".

Je souhaite avoir un commit après le traitement d'initialisation, puis après chacun des traitements d'enrichissement : je peux traiter un document déposé, comme un flux de plusieurs milliers de documents (le dernier exemple était de 35000 documents). Dans ce dernier cas, je peux tomber sur un flux xml non standard (résultant de l'appel webservice)  qui génère une exception et qui provoque in fine le rollback de l'ensemble de l'opération …

C'est ce que j'ai mis en pratique sur la base du snippet que j'ai posté ci-dessus, mais aucun "commit" n'est en fait réalisé : une exception générée après traitement de plus de 30.000 documents a provoquée le roll back de l'ensemble

Du coup, compte tenu de votre message, je ne sais plus quelle méthode utiliser.

Frédéric Marin
fmarin
Member II

Re: gestion de transaction [RESOLU]

bonsoir

je continue à avoir des difficultés à maîtriser les commit et rollback

Cette fois, j'utilise le retryingTransactionHelper spécifié par RGUINOT, mais sans succès : j'itède un certain nombre de fois sur le code :

   transactionService = (TransactionService)serviceRegistry.getTransactionService();
   RetryingTransactionCallback<Object> cr2 = new RetryingTransactionCallback<Object>()
      { public Object execute() throws Exception
          {
    if (debug) System.out.println("-la transaction commence");
      boolean bp=creer(nodeRef, fileName);
      if (debug) System.out.println("-la transaction finit");
      return bp;
      }
    };
    bp=(Boolean) transactionService.getRetryingTransactionHelper().doInTransaction(cr2);     
   if (bp)
   {
      System.out.println("!!!!!!!!!!!! incident sur création du document "
      + fileName + " - node="+nodeRef
      +" - on continue la route\n");
   }
   else
   {
      if (debug) System.out.println("$$$$$$$$"
      + "\n$$$$$$$$ création traitée avec succès - on continue la procédure"
      + "\n$$$$$$$$\n");
   }


en obtenannt bien le message de création avec succès, et je termine par un "null pointer" que j'ai inséré sans avoir aucune création d'enregistrée

quand je retire le "null pointer", j'obtiens bien l'ensemble des créations …

si vous avez une idée ? … le but est qand même de traiter plusieurs milliers d'itérations …

Frédéric Marin
rguinot
Customer

Re: gestion de transaction [RESOLU]

votre code n'est pas très indenté , mais j'ai l'impression que votre variable bp n'est pas déclarée dans le bon scope…
fmarin
Member II

Re: gestion de transaction [RESOLU]

Bonjour RGUINOT

j'avais modifié l'indentation directement dans le post, pour plus de lisibilité …, mais le voila mieux présenté, avec la déclaration de la variable bp
   boolean bp=false;     
   …
   transactionService = (TransactionService)serviceRegistry.getTransactionService();
   RetryingTransactionCallback<Object> cr2 = new RetryingTransactionCallback<Object>()
   { public Object execute() throws Exception
      {
         if (debug) System.out.println("-la transaction commence");
         boolean bp=creer(nodeRef, fileName);
         if (debug) System.out.println("-la transaction finit");
         return bp;
      }
   };
   bp=(Boolean) transactionService.getRetryingTransactionHelper().doInTransaction(cr2);     
   if (bp)
   {
      System.out.println("!!!!!!!!!!!! incident sur création du document "
         + fileName + " - node="+nodeRef
         +" - on continue la route\n");
   }
   else
   {
      if (debug) System.out.println("$$$$$$$$"
         + "\n$$$$$$$$ création traitée avec succès - on continue la procédure"
         + "\n$$$$$$$$\n");
   }


Frédéric Marin
fmarin
Member II

Re: gestion de transaction [RESOLU]

Bonsoir

humm … j'ai essayé deux solutions différentes, qui ne posent pas de problèmes à l'exécution, mais qui ne règlent pas la question des "commit" (ou alors, je n'ai pas tout compris …)

1ère solution (avec getTransactionService):
<java>
…/…
boolean bp=false;
TransactionService transactionService = (TransactionService)serviceRegistry.getTransactionService();
RetryingTransactionCallback<Object> cr2 = new RetryingTransactionCallback<Object>()
{ public Object execute() throws Exception
        {
      if (debug) System.out.println(ind+ " -la transaction commence");
      boolean bpi=creer();
      if (debug) System.out.println(ind+ " -la transaction finit");
      return bpi;
         }
};
bp=(Boolean) transactionService.getRetryingTransactionHelper().doInTransaction(cr2);     
…/…
</java>

2ème solution (avec getUserTransaction) :
<java>
…/…
UserTransaction trx = null;
boolean bpi = false;
try {
   trx = serviceRegistry.getTransactionService().getUserTransaction();
   trx.begin();
   bpi=creer();
   trx.commit();
} catch (Exception exc)
{
   if (trx != null)
   {
      try {
         if (debug) System.out.println(ind + " -la transaction rollback sur exception : "+ exc);
         trx.rollback();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}
…/…
</java>

détail : la méthode "creer" crée un document dans le repository

cela ne solutionne pas mon problème, car, quand je déclenche une exception java après ces séquences de code, le rollback se fait systématiquement

J'ai en fait réglé mon problème en traitant chaque document d'une manière unitaire et non par lot

je classe donc le post comme [RESOLU]

Frédéric Marin
fmarin
Member II

Re: gestion de transaction [RESOLU]

j'ai fini par comprendre l'erreur, grâce au post "How to write code with transactions" trouvé en fait lors d'une autre recherche.

La bonne solution est de passer par un RetryingTransactionCallback, l'autre solution étant susceptible de provoquer des effets de bords (deadlocks …).

encore faut il utiliser le paramètre PROPAGATION_REQUIRES, c'est à dire :

<java>Boolean result = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Boolean>(){
    public Boolean execute() throws Throwable {

      …
      if(val == null)
         throw new IllegalStateException("Val must not be null");

      return true;
    }  
//we need to setup a new transaction for this
}, false, true);</java>

merci cheffilet

Frédéric Marin