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 / ibatis / @Transactional [Data]


Sujet :

Spring Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 14
    Par défaut spring / ibatis / @Transactional
    hello,

    J'ai besoin de faire une série de requêtes d'insert, mais si l'un d'entre eux se passe mal il faut faire un roll back.
    ==> Vous avez compris, j'ai besoin de gérer une transaction au niveau service et non dao.

    Mon application est correctement configurée car le code suivant fonctionne (fonctionne car en debug on constate que le commit n'a bien lieu qu'à la fin de updatePerson) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class PartyDaoImp extends SqlMapClientDaoSupport implements PartyDaoInt {
     
        @Transactional
        public void updatePerson(Person person) {
            getSqlMapClientTemplate().update("updateParty", person, 1);
            getSqlMapClientTemplate().update("updatePerson", person, 1);
            System.out.println("Person updated");
        }
    }
    Par contre si je remonte d'un niveau pour mettre l'annotation @Transactionnal au niveau du service, ça ne le fait plus :
    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
    public class MainForTests {
        public static void main(String args[]) throws Exception {
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("conf/Spring_application_context.xml");
            PartyDaoInt partyDAO = (PartyDaoInt) ctx.getBean("partyDAO");
            testTransactions(partyDAO);
        }
     
        @Transactional
    	private static void testTransactions(PartyDaoInt partyDAO) throws DataAccessException {
        	Person person = partyDAO.selectPerson(2);
    		person.setGivenNames("bibi1");
    		partyDAO.insertPerson(person); // commit effectué sans attendre la fin de la procédure...
    		person.setGivenNames("bibi2");
    		partyDAO.insertPerson(person);
    	}
    }
    Je dis que ça ne fonctionne pas car en debug le commit du premier insert est fait alors que le second n'est pas encore exécuté...

    J'ai bien sûr passer pas mal de temps à chercher (toute la journée d'hier...) mais là je suis bloqué (vous aurez compris que je n'ai pas d'expérience de spring et les transactions...)

    Merci !

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Janvier 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5
    Par défaut
    Hello benibur

    Point 1 : il n'y a pas de magie, si tu veux des transactions entre l'appelant et l'appelé, il y faut de la place pour en caser la logique, aussi magique soit-elle avec les annotations !

    Donc si dans un même classe tu as une méthode non transactionnelle qui en appelle une méthode (annotée comme) transactionnelle, Spring ne peut pas injecter d'intercepteur (proxy dynamique ou instrumentation du binaire) qui va tester s'il y a déjà une transaction, sinon en créer une, puis exécuter le code métier ainsi transactionnalisé, enfin committer (ou rollback si exception runtime) la transaction (si elle a été créée).

    Donc créer aux moins deux instances, l'une avec la méthode non transactionnalisée et l'autre avec la méthode transactionnalisée appelée par la précédente.

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Par défaut
    Salut,

    @Transactional ne peut s'utiliser que sur des classes gérées par Spring. Ex : un bean Spring, un test unitaire avec le class runner de Spring, etc...
    J'ai pas l'impression que ta classe MainForTests rentre dans ce cas.
    Met ton traitement testTransactions() dans un bean Spring, avec l'annotation @Transactionnal, ca devrait marcher.

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par thebloodyman Voir le message
    Salut,

    @Transactional ne peut s'utiliser que sur des classes gérées par Spring. Ex : un bean Spring, un test unitaire avec le class runner de Spring, etc...
    J'ai pas l'impression que ta classe MainForTests rentre dans ce cas.
    Met ton traitement testTransactions() dans un bean Spring, avec l'annotation @Transactionnal, ca devrait marcher.
    +1

    et pour les tests unitaires il y a
    AbstractTransactionalSpringContextTests
    dont vous pouvez descendre vos propres UnitTest…

    vous pourrez spécifier l'emplacement de vos "applicationContext" par override de
    protected String[] getConfigLocations()

    autres méthodes intéressantes à overrider :
    public void onSetUpBeforeTransaction() throws Exception
    et
    public void onTearDownAfterTransaction() throws Exception

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 14
    Par défaut
    en effet, j'avais pas vu ça : il faut que je fasse changer mes lunettes !

    voici le code qui fonctionne : j'ai tout simplement mis la méthode qui est dans une transaction dans une classe générée via spring...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class PartyDaoTransaction {
     
        @Transactional
        public void testTransactions(PartyDaoInt partyDao) {
        	Person person = partyDao.selectPerson(2);
    		person.setGivenNames("bibi31");
    		partyDao.insertPerson(person);
    		person.setGivenNames("bibi32");
    		partyDao.insertPerson(person);
        }
    }
    et dans l'applicationContext.xml j'ai rajouté :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        <bean id="PartyDaoTransaction" class="dao.PartyDaoTransaction">
        </bean>
    bon, ça marche, mais là clairement il va falloir que je creuse les annotations pour comprendre :-)

    Merci à tous !


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/12/2008, 12h22
  2. [Spring][Hibernate] Transaction déclarative
    Par mauvais_karma dans le forum Hibernate
    Réponses: 13
    Dernier message: 03/07/2008, 17h09
  3. [iBatis] Spring Ibatis Mysql
    Par jamalmoundir dans le forum Persistance des données
    Réponses: 10
    Dernier message: 25/06/2008, 12h20
  4. [Data] [Spring][Ibatis] transactions non prise en compte
    Par nannous dans le forum Spring
    Réponses: 15
    Dernier message: 27/11/2007, 18h01
  5. [Data] [débutante][spring][ibatis] Error parsing XML
    Par stardust dans le forum Spring
    Réponses: 4
    Dernier message: 12/12/2006, 17h58

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