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 :

Spring, transactions et threads


Sujet :

Spring Java

  1. #1
    Candidat au Club
    Inscrit en
    Juillet 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut Spring, transactions et threads
    Bonjour,

    J'ai une application bâtie sur Spring qui stocke des données dans une base de données en utilisant Hibernate. Afin de ne pas ralentir l'appli, j'utilise un pool de threads (java.util.concurrent) pour les accès à la base de données.

    Je me retrouve donc avec un code du type (en version simplifiée) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    @Transactional(rollbackFor = Throwable.class)
    public void save(List<Value> values) {
        executor.execute(new Runnable() {
            public void run() {
                for ( Values val : values )
                    getHibernateTemplate.save(val);
            }
        });
    }
    L'ennui est qu'avec ce code, les transactions ne fonctionnent pas. Si une exception est levée dans ma méthode, le rollback n'est pas effectué, et des données sont stockées de manière permanente dans la base de données.

    D'où ma question : comment puis-je faire pour étendre mon contexte transactionnel à tous les threads utilisés pour les accès à la base ?

    Merci d'avance

  2. #2
    Membre averti
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Points : 368
    Points
    368
    Par défaut
    Une première remarque : tu es sûr de vraiment vouloir faire ça ? Tu lances ta sauvegarde dans un thread et il ne sera plus possible de faire remonter l'erreur...

    Si tu veux gérer un pool de threads pour l'accès à la base, tu peux utiliser C3P0 qui s'intègre avec Hibernate.

  3. #3
    Membre éclairé

    Inscrit en
    Juillet 2008
    Messages
    232
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 232
    Points : 837
    Points
    837
    Par défaut
    Je dis peut-etre une betise, mais pourquoi tu ne mets pas l'annotation rollbackFor juste avant la methode run?

  4. #4
    Candidat au Club
    Inscrit en
    Juillet 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci pour vos réponses

    Citation Envoyé par darkxan Voir le message
    Une première remarque : tu es sûr de vraiment vouloir faire ça ? Tu lances ta sauvegarde dans un thread et il ne sera plus possible de faire remonter l'erreur...
    C'est vrai que j'avais pas pensé à cet aspet-là... En tout cas, c'est sûr que je veux faire ça, histoire de rendre au plus vite la main à l'appli... Potentiellement, il peut y avoir un très grand nombre d'accès à la base (je n'ai pas la maîtrise sur ce nombre). Donc, c'est la seule solution que je vois pour l'instant.

    Citation Envoyé par darkxan Voir le message
    Si tu veux gérer un pool de threads pour l'accès à la base, tu peux utiliser C3P0 qui s'intègre avec Hibernate.
    Ok, je ne connaissais pas... Merci, je vais jeter un coup d'oeil à ça

    Citation Envoyé par bredelet Voir le message
    Je dis peut-etre une betise, mais pourquoi tu ne mets pas l'annotation rollbackFor juste avant la methode run?
    Ben, et là c'est peut-être moi qui dit une bêtise, si je met le @Transactional sur le run, je vais avoir plusieurs transactions, non ? Mon but serait d'avoir la même transaction pour toutes les données contenues dans la liste en paramètre de ma fonction... Et donc, ce qui m'intéresserait serait d'attendre que le dernier thread termine le traitement avec de faire un commit, ou bien de faire un rollback si j'ai eu une erreur dans au moins un des threads...

    Mais je sais pas si c'est possible....

    Merci encore

  5. #5
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Salut ,
    Tout d'abord, je voudrais juste clarifier que C3P0 n'est pas un pool de threads, mais un pool de connextions à la BD.

    Sinon:
    Ben, et là c'est peut-être moi qui dit une bêtise, si je met le @Transactional sur le run, je vais avoir plusieurs transactions, non ? Mon but serait d'avoir la même transaction pour toutes les données contenues dans la liste en paramètre de ma fonction... Et donc, ce qui m'intéresserait serait d'attendre que le dernier thread termine le traitement avec de faire un commit, ou bien de faire un rollback si j'ai eu une erreur dans au moins un des threads...
    Non, ça ne va pas créer une transaction pour chaque appel de run. le tout va tourner dans une seule transaction.
    Il suffit juste d'annoter la méthode save @Transactional), et c'est tout.

  6. #6
    Candidat au Club
    Inscrit en
    Juillet 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Non, ça ne va pas créer une transaction pour chaque appel de run. le tout va tourner dans une seule transaction.
    Il suffit juste d'annoter la méthode save @Transactional), et c'est tout.
    Merci pour ta réponse

    En fait, le @Transactional sur la méthode save, c'est ce que je faisais au début, mais en fait, ça ne marche pas... Si une erreur survient dans l'un des threads, les autres threads commitent en BD et du coup, je me retrouve avec un contenu inconsistant...

    Finalement, j'ai contourné le pb... Chaque thread est responsable d'une liste complète à sauvegarder, de sorte de ne pas distribuer le traitement sur plusieurs threads...

    Merci pour tout

  7. #7
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Je présumes que tes DAOs lancent des checked-exceptions, c'est ça ?

    Car par défaut, Spring ne fait de rollback que pour les unchecked-exceptions.

  8. #8
    Candidat au Club
    Inscrit en
    Juillet 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Je présumes que tes DAOs lancent des checked-exceptions, c'est ça ?
    Car par défaut, Spring ne fait de rollback que pour les unchecked-exceptions.
    Non, j'ai toutes sortes d'exceptions qui peuvent être levées... D'ailleurs, j'ai un doute là : si je mets le tag suivant :
    @Transactional(rollbackFor = Throwable.class)
    normalement, je fais bien un roolback quel que soit le type d'exception, non ?

    Merci

  9. #9
    Membre averti
    Profil pro
    Développeur Java
    Inscrit en
    Novembre 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2007
    Messages : 301
    Points : 368
    Points
    368
    Par défaut
    Oui, tu fais un rollback pour tous les types d'Exception et d'Error.

Discussions similaires

  1. [Data] spring + transaction
    Par zorro13 dans le forum Spring
    Réponses: 6
    Dernier message: 12/11/2008, 18h55
  2. Problème transaction et thread
    Par valoji dans le forum Bases de données
    Réponses: 9
    Dernier message: 27/10/2008, 16h19
  3. Réponses: 1
    Dernier message: 12/06/2006, 19h02
  4. [ spring ] transaction tomcat
    Par hocinema dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 11/10/2005, 21h04

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