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 :

Problème de transaction [Data]


Sujet :

Spring Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 22
    Par défaut Problème de transaction
    Bonjour à tous !

    Je travaille actuellement sur un projet en spring et je rencontre quelques difficultés vis à vis de la gestion des transactions.

    Quelques éléments d'informations :
    - Projet entièrement mavenisé en spring 2.5.6
    - Hibernate pour la persistence des données (3.3.1.GA)
    - Spring Security pour l'aspect authentification (2.0.5)
    - Quartz pour les jobs schedulé
    - Un peu d'AOP pour certains éléments transverses (spring-aspect 2.5.6)

    Au niveau des spécificités, il faut savoir que j'utilise un filtre openSessionInView (OSIV) pour avoir accès aux propriétés lazy au niveau de mes jsp (singleSession = true, flushMode = auto).

    Je pense avoir tout dit, s'il manque des renseignements, hésitez pas à me le faire savoir ^^

    Venons-en aux faits ! Voici la configuration de ma couche DAO:

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    [...]
    	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    			<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    	<tx:annotation-driven transaction-manager="txManager"/>
     
    <bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    		<property name="properties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
    				<prop key="hibernate.show_sql">false</prop>
     
    				<!-- Gestion du cache -->
    				<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
    				<prop key="hibernate.second_level_cache">true</prop>
    				<prop key="hibernate.use_query_cache">true</prop>
    				<prop key="net.sf.ehcache.configurationResourceName">/conf/ehcache.xml</prop>
    				<prop key="hibernate.generate_statistics">true</prop>
    				<prop key="hibernate.cache.use_structured_entries">true</prop>
    				<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
    			</props>
    		</property>
    	</bean>
     
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="mappingLocations">
    		 	<value>classpath*:hibernate/**/*.hbm.xml</value>
    		 </property>
    		<property name="dataSource" ref="dataSource"></property>
    		<property name="hibernateProperties" ref="hibernateProperties" />
    	</bean>
    (La partie coupée ne contient que les accès à la base)

    J'ai créé le service suivant:
    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
     
    @Service("I_IndividuService")
    @Transactional
    public class IndividuService implements I_IndividuService {
    	@Autowired
    	private IndividuDAO individuDAO;
     
    	@Transactional(readOnly = true,
    			propagation = Propagation.REQUIRED,
    			rollbackFor = Exception.class)
    	public void save(final Individu individu) throws Exception {
    		individu.setFirstname("toto");
    		individu.setLastname("test");
     
    		individuDAO.saveOrUpdate(individu);
     
    		throw new Exception("ROLLBACK !");
    	}
    }
    Le dao associé est le suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    @Repository
    public class IndividuDAO  extends HibernateDaoSupport {
    	public void saveOrUpdate(Individu ind) {
    		getHibernateTemplate().saveOrUpdate(ind);
    	}
    }
    Lorsque j'exécute ce test, mon M. toto Test est créé dans la base de données, donc:
    - le readOnly = true ne fonctionne pas
    - le rollback ne fonctionne pas (alors que l'exception est correctement levée).

    Qu'est-ce que j'ai oublié comme conf/code pour faire en sorte que M. toto Test ne vienne pas polluer ma base de données -et accessoirement pour que mes transactions fonctionnent - ?

    Merci d'avance !

  2. #2
    Membre expérimenté Avatar de aymen83
    Inscrit en
    Décembre 2007
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 271
    Par défaut
    salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	@Transactional(readOnly = true,
    			propagation = Propagation.REQUIRED,
    			rollbackFor = Exception.class)
    une transaction readOnly c'est pour dire lire,mais tu es entrain de créer une transaction juste pour lire des données, alors que dans ton code t'es entrain de faire un save?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    @Transactional(readOnly = true,
    			propagation = Propagation.SUPPORT,
    			)
    ceci permet de lire des données.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	@Transactional(readOnly = false,
    			propagation = Propagation.REQUIRED,
    			rollbackFor = Exception.class)
    ceci pour écrire.
    mais attention la combinaison readOnly, propagation ça varie d'un fournisseur à un autre et d'un driver un autre

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 22
    Par défaut
    C'est bien là le problème : je place une transaction en readOnly mais lorsque j'execute mon service, les données sont écrites

    Ce que je souhaite faire via cette exemple, c'est mettre en exergue le fait que la transaction fonctionne comme je m'y attends:
    - si je configure la transaction en readOnly, je ne veux pas que mes données soient modifiées
    - si je lève une exception dans le service (en read/write), je veux que mes données modifiées soient rollbackées.

    Bref, ce qu'on attends d'une transaction

  4. #4
    Membre expérimenté Avatar de aymen83
    Inscrit en
    Décembre 2007
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 271
    Par défaut
    Citation Envoyé par miles_ Voir le message
    C'est bien là le problème : je place une transaction en readOnly mais lorsque j'execute mon service, les données sont écrites

    Ce que je souhaite faire via cette exemple, c'est mettre en exergue le fait que la transaction fonctionne comme je m'y attends:
    - si je configure la transaction en readOnly, je ne veux pas que mes données soient modifiées
    - si je lève une exception dans le service (en read/write), je veux que mes données modifiées soient rollbackées.

    Bref, ce qu'on attends d'une transaction
    si tu met readOnly à true ça ne veux pas dire que ta transaction ne va pas écrire dans la base. c'est juste pour "optimiser la transaction"
    mais effectivement ça devrait lever une exception puisque tu crée une transaction readOnly et tu insere des données

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 22
    Par défaut
    si tu met readOnly à true ça ne veux pas dire que ta transaction ne va pas écrire dans la base. c'est juste pour "optimiser la transaction"
    Tiens je ne savais pas ça

    Au final, j'ai eu l'idée lumineuse de bidouiller mon filtre OSIV, j'ai remplacé le flushMode AUTO à NEVER.

    Lorsque j'exécute ce service, j'ai une nouvelle exception de levée (je l'ai plus en tête mais en gros, il me disait qu'il pouvait pas commiter).

    Je corrige donc mon code, readOnly = false, j'effectue mon test avec mon exception "rollback", ce n'est toujours pas commité.

    Je supprime cette exception, le commit se fait normalement.

    VICTORY !

    Merci pour tes réponses, ça m'a permi d'explorer d'autres pistes que je n'avais pas envisagées jusqu'à présent

  6. #6
    Membre expérimenté Avatar de aymen83
    Inscrit en
    Décembre 2007
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 271
    Par défaut
    pour le flush mode MANUAL devrait marché aussi

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

Discussions similaires

  1. [delphi][interbase]problème de transaction
    Par daheda dans le forum Bases de données
    Réponses: 4
    Dernier message: 26/10/2006, 09h12
  2. Problème de Transactions
    Par blaspalles dans le forum Access
    Réponses: 4
    Dernier message: 18/09/2006, 17h05
  3. problème de transaction et load data
    Par jccanut dans le forum Installation
    Réponses: 6
    Dernier message: 14/09/2006, 11h38
  4. [SQL 2k] Problème de transaction choisie comme victime
    Par Actarion dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 04/07/2006, 17h17
  5. Encore un petit problème de transaction
    Par devdev dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 24/03/2005, 16h13

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