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 ne marche pas


Sujet :

Spring Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut @Transactional ne marche pas
    Bonjour,

    J'utilise l'annotation @Transactional pour gérer les transactions au niveau de la connexion à la base de données. Mais ça ne marche pas. C'est comme si l'annotation n'était pas détectée par Spring et que ma Connection était en autocommit true. Du coup, lorsque je fais un rollback, la transaction est quand même commitée.
    Ça fait un bout de temps que je cherche, sans trouver la cause du problème. Si vous pouviez éclairer ma lanterne
    Pour info, ma base de données est dans un conteneur Docker

    Voici ma configuration :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    @Configuration
    @EnableTransactionManagement
    @EnableWebMvc
    @ComponentScan("fr.test")
    public class SpringConfig extends WebMvcConfigurerAdapter {
     
        private DriverManagerDataSource ds = new DriverManagerDataSource();
     
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/css/**", "/js/**");
        }
     
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
     
        @Bean
        public ViewResolver viewResolver() {
            InternalResourceViewResolver bean = new InternalResourceViewResolver();
            bean.setViewClass(JstlView.class);
            bean.setPrefix("/WEB-INF/jsp/");
            bean.setSuffix(".jsp");
            return bean;
        }
     
        @Bean
        public DriverManagerDataSource dataSource() {
            ds.setDriverClassName("com.mysql.jdbc.Driver");
            ds.setUrl("jdbc:mysql://172.17.0.2:3306/test");
            ds.setUsername("test");
            ds.setPassword("123");
            return ds;
        }
     
        @Bean
        public DataSourceTransactionManager txManager() {
            DataSourceTransactionManager txManager = new DataSourceTransactionManager();
            txManager.setDataSource(ds);
            return txManager;
        }
    Et voici un extrait de mon service et de mon 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
    33
    34
    35
    36
    37
    38
    39
    40
     
    @Service
    public class RegisterServiceImpl implements IRegisterService {
     
        @Autowired
        private RegisterDAO registerDAO;
     
        @Transactional(rollbackFor=Throwable.class)
        @Override
        public long register(VisitorModel visiteur) throws BusinessException {
            return registerDAO.register(visiteur, utilisateur);
        }
    }
     
    @Repository
    public class RegisterDAO {
     
        @Autowired
        private DataSource ds;
     
        public long register(VisitorModel visitor) {
            String sql = "insert into visitor (email, password) values (?, ?)";
     
            try {
                Connection c = ds.getConnection();
                PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                ps.setString(1, visitor.getEmail());
                ps.setString(2, visitor.getPassword());
     
                ps.executeUpdate();
     
                ResultSet rs = ps.getGeneratedKeys();
                //rs.next(); requis, donc une exception est levée lorsque cette instruction est commentée
                return rs.getLong(1);
            } catch (SQLException e) {
                // pas de rollback lorsqu'une exception est levée
                throw new TechnicalException(e);
            }
        }
    }

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Est-ce que ton exception personnalisée utilise l'annotation @ApplicationException(rollback = true) ?

  3. #3
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 135
    Points : 391
    Points
    391
    Par défaut
    Ton probleme est que ton transaction manager n'est pas sur ta datasource.
    Essaye ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
       @Bean
        public DataSourceTransactionManager txManager() {
            DataSourceTransactionManager txManager = new DataSourceTransactionManager();
            txManager.setDataSource(dataSource());
            return txManager;
        }

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Citation Envoyé par fr1man Voir le message
    Est-ce que ton exception personnalisée utilise l'annotation @ApplicationException(rollback = true) ?
    Bonjour, merci pour ta réponse.

    D'où vient cette annotation ApplicationException ? Je ne l'ai dans aucune de mes dépendances.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Citation Envoyé par bilgetz Voir le message
    Ton probleme est que ton transaction manager n'est pas sur ta datasource.
    Essaye ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
       @Bean
        public DataSourceTransactionManager txManager() {
            DataSourceTransactionManager txManager = new DataSourceTransactionManager();
            txManager.setDataSource(dataSource());
            return txManager;
        }
    Si, mon DataSource est instancié une seule fois, et je garde la référence en attribut (ds)

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Je me suis un peu emballé c'est une annotation que j'utilise avec des EJBs et provient du package javax.ejb.
    N'y a t il pas un équivalent dans les API Spring ?

  7. #7
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    Par défaut
    Bonjour,

    Citation Envoyé par verbose
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @Transactional(rollbackFor=Throwable.class)
    Spring fait automatiquement un rollBack en cas d'un RuntimeException. Si tu as une Exception personnalisée, c'est que tu dois mettre sur rollbckFor
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @Transactional(rollbackFor=TonException.class)
    je ne comprend pas, à quel moment tu veux faire un rollBack dans ton code? Tu peux nous expliquer un peu plus sur ton problème?

    A+.

  8. #8
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    Par défaut
    Si c'est pour une classe de test et que tu ne veux pas écrire dans la base, tu as l'annotation @RollBack.

Discussions similaires

  1. [MySQL] Transactions SQL marche pas
    Par vocal94130 dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 01/06/2010, 12h50
  2. 'SHOW TABLES' marche pas sous postgresql !?
    Par fet dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 13/05/2004, 09h28
  3. Réponses: 9
    Dernier message: 07/05/2003, 12h57
  4. [GifDecoder] marche pas dans applet avec IE
    Par formentor dans le forum Applets
    Réponses: 2
    Dernier message: 06/05/2003, 10h43
  5. Sysdate qui marche pas ??
    Par StouffR dans le forum Langage SQL
    Réponses: 4
    Dernier message: 28/08/2002, 13h23

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