Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problèmes transaction java mysql

Sujet résolu
    29 août 2016 à 12:56:24

    Salut à tous !

    Je développe une application Java qui utilise une base de données MySQL InnoDB.

    J'ai un sacré souci, je souhaite utiliser les transactions pour garder l'intégrité de ma base de données (exemple : sur la gestion d'un forum, si je veux créer un message, si je veux insérer d'abord le message dans la bdd et ensuite insérer le sujet, je veux être sûr que si le sujet ne s'est pas crée correctement, que le message soit supprimé).

    Pour faire ça j'utilise les transactions :

    Avant toutes mes requêtes d'insertion, je crée un SavePoint. Si une exception est levée, je rollback sur le save point. Sinon je commit en utilisant la méthode (connection.commit()).

    Problème : J'insère le message (la méthode qui fait ça me retourne un identifiant) mais quand je vais voir ma base de données, le message n'y est pas...

    Je précise qu'avant de faire un SavePoint j'utilise la méthode connexion.setAutoCommit(false)

    N'hésitez pas si vous avez des questions.

    Je vous remercie d'avance pour vos réponses ! :)

    • Partager sur Facebook
    • Partager sur Twitter
      29 août 2016 à 13:46:34

      Bonjour.

      Les modifications faites dans une transaction ne sont pas (par défaut) visibles par les autres utilisateurs.
      Les modifications seront partagées une fois le commit fait. 

      Si tu veux regarder les modifications en cours, jette un oeil à "read uncommitted"
      (à utiliser juste en mode débug) 

      • Partager sur Facebook
      • Partager sur Twitter
      Angular 2 est l'avenir, jQuery c'est de la merde !!! - Java 8 c'est l'an 2016+ (programmez en 1 ligne)
        29 août 2016 à 14:06:57

        Salut Pinguet62 !

        Alors effectivement c'est ce qu'il se passe... Est-ce qu'il existe un paramétrage de MySQL pour que les transactions soient visibles par les utilisateurs (que ça se mette dans la table mais que si y'a un problème qu'on puisse Rollback ?).

        En effet, j'ai un problème de clé étrangère tant que je n'ai pas commit et impossible de faire mes insertions du coup...

        • Partager sur Facebook
        • Partager sur Twitter
          29 août 2016 à 14:24:38

          Le fonctionnement est totalement normal : c'est le principe des transactions :

          • Si une erreur se présente alors tu feras un rollback, et donc les autres utilisateurs ne verront rien.
          • Si des différentes opérations se font avec succès, alors lors du commit tous les utilisateurs verront les modifications

          Quel est exactement ton problème de clé étrangère ?

          • Partager sur Facebook
          • Partager sur Twitter
          Angular 2 est l'avenir, jQuery c'est de la merde !!! - Java 8 c'est l'an 2016+ (programmez en 1 ligne)
            29 août 2016 à 14:33:14

            Alors j'ai fait comme tu m'as dit il y'a quelques semaines j'utilise des services qui font appel a un DAO pour faire mes requêtes SQL.

            Je fais une application qui gère des articles qui appartiennent à une activité.

            Deux types d'article : les articles avec recette (qui seront vendus) et des articles sans recettes.

            Voici le code d'insertion de mon article dans la base de données :

            private void enregistrerArticle() throws DAOException,DAOConfigurationException{
            		//Enregistrement dans la table article
            		this.article.setIdArticle(articleService.insererArticle(this.article,this.activiteAvecRecette.getIdActivite()));
            		//enregistrement de l'achat
            		if(this.article.getAchat()!=null){
            			//Insertion de l'achat
            			this.article.getAchat().setIdAchat(achatService.insererAchat(this.article.getIdArticle(),this.article.getAchat()));
            			if(this.article.getAchat().getFraisGestion()!=null){
            				//Insertion des frais de gestion
            				this.article.getAchat().getFraisGestion().setIdFraisGestion(this.fraisGestionService.insererFraisGestion(this.article.getAchat().getIdAchat(),this.article.getAchat().getFraisGestion()));
            			}
            		}
            		//Insertion de l'article avec recette
            		this.articleAvecRecetteService.insererArticleAvecRecette(this.article);
            		if(cb_articleSubventionne.isSelected()){
            			//Insertion de la subvention dans la table subvention
            			enregistrerSubvention();
            		}
            	}

            ce que je veux simplement faire est la chose suivante : Je souhaite sauvegarder l'état de ma base avant de faire appel à la méthode enregistrerArticle().

            Si l'enregistrement de l'article se passe bien, je veux commit toutes mes modifs.

            Si par contre il y'a un quelconque problème d'insertion dans la table article_avec_recette, là je veux rollback (donc revenir au point de sauvegarde que j'ai fait avant l'appel à la méthode enregistrerArticle().

            Le souci, c'est que lorsque j'insère dans la table ARTICLE un article, l'identifiant est bien renvoyé, mais la ligne n'est pas dans la table et lorsque mon programme passe à l'instruction insererArticleAvecRecette(this.article), il me dit qu'il y'a un problème de clé étrangère... Normal la ligne n'apparaît pas...

            Voilà j'espère avoir été assez clair :) Merci Pinguet62 pour tes réponses

            • Partager sur Facebook
            • Partager sur Twitter
              29 août 2016 à 14:46:10

              Essaye déjà d'insérer la première données (article) et de commiter une fois fait. (supprime le bloc "Insertion de l'article avec recette")
              Vérifie ensuite que ta ligne est en base de données.
              • Partager sur Facebook
              • Partager sur Twitter
              Angular 2 est l'avenir, jQuery c'est de la merde !!! - Java 8 c'est l'an 2016+ (programmez en 1 ligne)
                29 août 2016 à 14:56:02

                OK alors je sais d'où ça vient. J'ai suivi le tuto d'openclassrooms et à chaque fin de requête du dao, ils font une méthode DAOUtilitaire.fermeturesSilencieuses(resultSet,preparedStatement,connection)

                Cette méthode fait appel à connection.close();

                Or, comme rien n'est commit, l'appel à connection.close() vire la transaction.....

                Du coup je ne sais pas comment faire pour gérer la fermeture de la connexion à la base de données car ça m'embête d'appeler une méthode dans le controller pour faire ma fermeture moi même...

                • Partager sur Facebook
                • Partager sur Twitter
                  29 août 2016 à 15:18:45

                  Normalement tu devrais avoir un truc du genre :

                  class MyService {
                      void myMethod() {
                          // ouverture connexion
                          // begin transaction
                          // ... tes actions
                          // commit ou rollback (try/catch)
                          // fermeture connexion
                      }
                  }

                  Ton contrôleur n'a pas à gérer la BDD, c'est ton service qui le fera.

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Angular 2 est l'avenir, jQuery c'est de la merde !!! - Java 8 c'est l'an 2016+ (programmez en 1 ligne)
                    29 août 2016 à 15:27:47

                    Arf, leur tuto est pas bon alors...

                    voici ce que j'ai dans un controller :

                    @Override
                    	public Integer insererArticle(Article article,Integer idActivite) throws DAOException,
                    			DAOConfigurationException {
                    		ConnexionBDD connexion=ConnexionBDD.getInstance();
                    		ArticleDAO articleDAO=new ArticleDAOMySQL(connexion);
                    		return articleDAO.insererArticle(article,idActivite);
                    	}

                    Fait chi*** faut que je refasse tout...

                    • Partager sur Facebook
                    • Partager sur Twitter
                      29 août 2016 à 15:38:24

                      Ouè l'appel de DAO/Connection directement dans la JSP c'est pas top ^^
                      Le cours mélange 2 technologies complètement indépendances (couche Service étant là pour faire l'intermédiaire).
                      Et en pratique, dans le vrai Java EE, on profite des annotations qui sont là pour créer des proxy qui vont justement gérer les connexions sans avoir à le faire manuellement (plus haut niveau dans les compétences Java).

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Angular 2 est l'avenir, jQuery c'est de la merde !!! - Java 8 c'est l'an 2016+ (programmez en 1 ligne)
                        29 août 2016 à 15:41:42

                        Waw OK...

                        Ben écoute merci beaucoup pour tes réponses, j'ai du sale refactoring à faire...

                        A bientôt :)

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Problèmes transaction java mysql

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown