IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

@Transactional(readOnly = false, propagation = Propagation.REQUIRED , rollbackFor = Exception.class)


Sujet :

Spring Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut @Transactional(readOnly = false, propagation = Propagation.REQUIRED , rollbackFor = Exception.class)
    Bonjour

    J'ai deja posté ma question sur un autre poste (http://www.developpez.net/forums/d66...ne-fonctionne/), mais vu qu'il était marqué comme "résolu" (avant d'avoir posté ma question) , j'ai bien peur que personne ne me vienne en aide... donc si la question suivante n'a pas lieu d'être ici , veuillez m'en excuser ...


    voici 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
     
    @Service("faxServiceTarget")
    @Scope("singleton")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public class FaxService implements IFaxService {
     
      public IFaxModel saveFaxModel(IFaxModel faxModel) {
            return getFaxDao().saveFaxModel(faxModel);
        }
     
         public IFaxModel monTest(IFaxModel faxModel) throws Exception {
            faxModel = saveFaxModel(faxModel);
            if (true) {
                throw new Exception("montest esception");
            }
            return faxModel;
        }
    }
    mon test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     @Test
          public void saveFaxModel2() {
              IFaxModel faxModel_1 = (IFaxModel) getXmlBeanFactory().getBean("faxModel_1");
            try {
                faxModel_1 = getFaxService().monTest(faxModel_1);
            } catch (Exception e) {
                e.printStackTrace();  
            }
            assert faxModel_1 != null && faxModel_1.getId() != null && faxModel_1.getFaxResults() != null;
          }
    Je ne sais pas si j'ai bien fait mais j'ai la notion de transaction au niveau de ma classe et non au niveau des méthodes (c'est peut être de la que vient mon problème ? d'ailleurs quels sont les avantages et inconvénients d'un tel choix )

    Ce que je ne comprend pas c'est pourquoi la sauvegarde de mon object est bien faite en base

    Hikage (dans le poste qui est marque comme résolu) nous dit :

    Pour la gestion des transactions, Spring créer un proxy. Lorsqu'une methode du service est appelée par une autre composant ( dans lequel le service à été injecté ), l'appel passe par le proxy qui va ouvrir la transaction, faire l'appel à ta methode, et au retour gérer la fin de transaction.

    Or ici, testTransaction(), qui est ta methode transactionnelle est appelée directement dans le service, et donc tu ne passe pas dans le proxy.
    Résultat, la transaction n'est pas gérée par Spring.
    Mon problème proviendrait il du faite que mon save et ma génération de l'exception dans mon service sont faite dans deux transactions différentes vu que j'appelle saveFaxModel depuis mon service et non directement depuis mon test ?

    Si c'est le cas comment faire pour que les opérations faites durant un enchaînement de méthodes du même service soient atomique, c'est à dire que si une des méthodes lève une exception, les méthode précédemment exécutées soient "RollBacké"

    J'ai trouvé une réponse sur un autre poste (http://www.developpez.net/forums/d51...e-fonctionner/) que j'ai implementé en changeant ma classe service comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    @Service("faxServiceTarget")
    @Scope("singleton")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED , rollbackFor = Exception.class)
    public class FaxService implements IFaxService {
    [...]
    }
    La sauvegarde de mon objet ne se fait pas en base....

    Quand même , au cas où..., si quelqu'un peut me confirmer que c'est la bonne manière de faire ...

    D'avance merci, et désolé de reprendre des postes marqués comme résolus (mais qui me laisse quand même dans le doute :p)

  2. #2
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Par défaut
    Pour avoir un réglage plus fin, je pense qu'il vaut mieux annoter les méthodes plutôt que la classe, et appeler des méthodes privées (celle qui te génère l'exception par exemple).
    Dans ton exemple, tu mettrais saveFaxModel privée, et l'annotation sur monTest.

  3. #3
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Hello Patriarch24

    Merci pour tes précisions sur les différences entre les annotations sur la classe ou sur les méthodes de la classe (et la rapidité de ta réponse)

    Dans ton exemple, tu mettrais saveFaxModel privée, et l'annotation sur monTest.
    Le (ptit ) hic, c'est que cette méthode saveFaxModel doit aussi être transactionnelle car elle est appelé par d'autres classes ...

    Ce qui me surprend c'est qu'il faille préciser " rollbackFor = Exception.class" dans la définition de la transaction dans mon exemple @Transactional(readOnly = false, propagation = Propagation.REQUIRED , rollbackFor = Exception.class)

    Je trouve ça très bien cette souplesse mais peux tu me confirmer que c'es "LA" bonne méthode pour rendre des transactions "atomiques" (c'est à dire que si une des méthodes lève une exception, les méthode précédemment exécutées soient "RollBacké"

    De plus dans la docs, mon anglais n'étant pas mon point fort (oui je sais c'es tres mal, mais j'y travail ) j'ai du mal à comprendre la différence entre les différents modes de propagation ( propagation = Propagation.REQUIRED, propagation = Propagation.NESTED .... )
    Abuserai je si je te demandais d'éclairer ma lanterne ?

    Dans tous les cas merci pour ton aide !
    a+

  4. #4
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Par défaut
    Pour une explication sur les transactions :
    http://www.karlverger.com/developpem...g-framework-31
    Quant à te confirmer qu'il s'agit de la bonne méthode, malheureusement, je crains que tu ne puisses pas t'en sortir comme ça, car comme dit précédemment :
    qui est ta methode transactionnelle est appelée directement dans le service, et donc tu ne passe pas dans le proxy.
    Résultat, la transaction n'est pas gérée par Spring.
    Il faut trouver une autre méthode. Personnellement, je n'appelle jamais une méthode publique d'un service à partir d'une autre, je m'arrange pour que les deux appellent une méthode privée. Tu est ainsi dans une transaction, et tu maitrises le tout grâce aux annotations de méthodes.
    Je serais toi, je mettrais "return getFaxDao().saveFaxModel(faxModel);" dans une méthode privée.

  5. #5
    Membre averti Avatar de Hyperion99
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Merci pour le lien, je vais étudier ca ce soir

    Personnellement, je n'appelle jamais une méthode publique d'un service à partir d'une autre, je m'arrange pour que les deux appellent une méthode privée. Tu est ainsi dans une transaction, et tu maitrises le tout grâce aux annotations de méthodes.
    Et dans le cas où deux services s'appelent entre eux ?
    par exemple

    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
     
     
    @Service("MonService arget")
    @Scope("singleton")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public class MonService implements IMonService {
       IFaxService faxService;
     
     
      public IFaxModel saveFaxModel(IFaxModel faxModel) {
               getFaxService().saveFaxModel(faxModel);         
       }
     
         public void doSomethingElse(IFaxModel faxModel) throw Exception{
              saveFaxModel2(faxModel);
                throw new Exception("montest esception");
        }
    tu me conseilles de remplacer ca par

    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
    @Service("MonService arget")
    @Scope("singleton")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public class MonService implements IMonService {
       IFaxService faxService;
    
    
       private IFaxModel saveFaxModel2(IFaxModel faxModel) {
               getFaxService().saveFaxModel(faxModel);         
       }
    
         public void doSomethingElse(IFaxModel faxModel) throw Exception{
               saveFaxModel2(faxModel);
                throw new Exception("montest esception");
        }    
    
        public void saveFaxModel(IFaxModel faxModel) {
               saveFaxModel2(faxModel);         
       }
    dans tous les cas , merci pour tes conseills !!!
    a+

  6. #6
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Par défaut
    Et dans le cas où deux services s'appelent entre eux
    Ca ne pose pas de problème, comme tu injectes les services via Spring, tu passes à travers le proxy du service qui gère les transactions.

Discussions similaires

  1. Réponses: 0
    Dernier message: 12/05/2015, 23h30
  2. Propagation d'evenement dans une classe
    Par C_le_N dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 21/07/2010, 11h28
  3. Réponses: 3
    Dernier message: 21/04/2008, 17h25
  4. Réponses: 11
    Dernier message: 26/09/2007, 11h28
  5. [.NET][C#] DataGrid ReadOnly=false sur une ligne
    Par arnauann dans le forum Windows Forms
    Réponses: 1
    Dernier message: 01/06/2006, 17h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo