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

PHP & Base de données Discussion :

transaction validée malgrès une erreur [PDO]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    530
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 530
    Par défaut transaction validée malgrès une erreur
    Bonjour à tous,

    J'ai une transaction dans laquelle je cherche à effectuer plusieurs UPDATE dans la même table.

    J'ai pu constater que parfois tous les UPDATE ne sont pas effectués et pourtant cela ne déclenche pas le ROLLBACK...

    Je l'ai vérifié en supprimant l'une des lignes dont je demande l'UPDATE dans la table "clients", je pense que dans la mesure on je demande l'UPDATE d'une ligne qui n'existe pas, cela doit bien lever une erreur ?

    Je précise que comme cela m'est déjà arrivé, j'ai bien vérifié que les Tables concernées sont de type InnoDB

    Voici le script :

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    $guidAcc=(isset($_POST['guidAcc'])) ? ($_POST['guidAcc']=="a") ? 1 : 0 : 0;
     
    $tabClient=array();
    $tabType=array();
    $tabIDRef=array();
    $tabMontant=array();
     
    for($i=0; $i<=$_POST['nbr']; $i++){
    $tab=explode("|",$_POST['acti_'.$i]);
     
    $tabMontant[]=$_POST['montant_'.$i];
    $tabClient[]=$tab[0];
    $tabType[]=$tab[1];
    $tabIDRef[]=$tab[2];
    }
     
    $clientBdd=implode("/",$tabClient);
    $refBdd=implode("/",$tabIDRef);
    $typeBdd=implode("/",$tabType);
    $montantBdd=implode("/",$tabMontant);
     
    ///////////////////////////////// ECRITURE DANS LA TABLE FACTURES ////////////////////////////////////////////////
     
    ${"dbh".$rep}->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    ${"dbh".$rep}->beginTransaction();
     
    try{ // DEBUT DE TRANSACTION
     
    $query_inFacture="INSERT INTO factures_vendeurs SET 
    date='".date('Y-m-d')."',  
    IDVendeur=".$IDvendeur.", 
    IDClients='".$clientBdd."', 
    actis='".$refBdd."',
    type='".$typeBdd."',
    guidAcc=".$guidAcc.",  
    montant='".$montantBdd."'";
     
    ${"dbh".$rep}->exec($query_inFacture);
    $IDFacture=${"dbh".$rep}->lastInsertId();
     
    foreach($tabClient as $key=>$value){
     
    $query_rsClient="SELECT revendPaye, typeRef, IDRef FROM clients WHERE ID=".$value;
     
    $rsClient=${"dbh".$rep}->query($query_rsClient);
    $row_rsClient = $rsClient->fetch(PDO::FETCH_ASSOC);
     
    $tabPaye=explode("/",$row_rsClient["revendPaye"]);
    $tabIDRefClient=explode("/",$row_rsClient["IDRef"]);
    $tabTypeClient=explode("/",$row_rsClient["typeRef"]);
     
    $tabCompare=array();
     
    foreach($tabTypeClient as $cle=>$valeur)$tabCompare[]=$valeur."_".$tabIDRefClient[$cle];
     
    $num=array_search($tabType[$key]."_".$tabIDRef[$key], $tabCompare);
    $tabPaye[$num]=$IDFacture;
    $majPaye=implode("/",$tabPaye);
     
    $query_rsMajClient="UPDATE clients SET revendPaye='".$majPaye."' WHERE ID=".$value;
    ${"dbh".$rep}->exec($query_rsMajClient);
    $tabCompare="";
     
    }; // FIN DE FOREACH
     
    ${"dbh".$rep}->commit();
    echo 1;
    } 
    catch(Exception $e){
    ${"dbh".$rep}->rollBack();
    echo 0;
    }; // FIN DE TRANSACTION
    Dans un premier temps quelqu'un peut-il me dire pourquoi il n'y a pas de rollback lorsqu'une erreur se produit ?

    Dans les cas que j'ai testé l'UPDATE doit se faire sur une trentaine de lignes de la TABLE "clients", ce qui veut dire une trentaine de requêtes UPDATE...

    Je ne vois pas comment faire une seule requête d'UPDATE pour mettre à jour 30 lignes en même temps...

    Est-ce possible ? est-ce que ça changerai quelque chose ?

    Merci d'avance pour vos réponses

  2. #2
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Bonjour,

    Citation Envoyé par Alexdezark Voir le message
    je pense que dans la mesure on je demande l'UPDATE d'une ligne qui n'existe pas, cela doit bien lever une erreur ?
    non. Ce n'est pas une raison suffisante pour effectuer un rollback

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    530
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 530
    Par défaut
    Bonjour et merci de ta réponse,

    Bon d'accord, j'avais fait ça pour faire un test mais dans les faits, les problèmes que j'ai eu n'étaient pas dus à cela.

    En fait j'ai eu plusieurs cas ou l'un des clients de la table "clients" n'était pas mis à jour.

    Il avait bien été inscrit dans la facture par la première requête d'insertion mais la colonne de la table "clients" qui indique le numéro de la facture sur laquelle figure le client n'était pas mise à jour, ce qui laisse supposer qu'une erreur s'est produit.

    Cela fait que le client figure bien sur la facture mais est quand même proposé de nouveau dans la liste des clients en attente de facturation... c'est génant...

    Depuis ce matin je cherche à reproduire l'erreur mais je n'y arrive pas, cela indiquerai que le problème ne vient pas du script mais plutôt d'un temps d'exécution de script dépassé ou d'une micro coupure.

    Quelle serait la réaction de la transaction en cas de temps d'exécution d'un script dépassé ?

  4. #4
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Citation Envoyé par Alexdezark Voir le message
    Quelle serait la réaction de la transaction en cas de temps d'exécution d'un script dépassé ?
    un beginTransaction() passe ta base en mode autocommit = off ce qui veut dire qu'aucune requete effectuée après l'instruction beginTransaction() ne sera executée (ie: ta transaction complete n'est pas effectuée) tant qu'un commit() ne sera trouvé.

    Es tu sur de ton SQL de mise à jour ? Je rappelle qu'un update ne mettant à jour 0 lignes ne sort pas en erreur

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    530
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 530
    Par défaut
    Citation Envoyé par Madfrix Voir le message
    Es tu sur de ton SQL de mise à jour ?
    Et bien dans la mesure ou les autres clients qui figurent sur la facture sont mis à jour, oui je suis sûr de la validité de ma requête.

    MAIS, la question que je me pose dans la mesure ou je passe par une requête SELECT pour créer le tableau qui sera mis à jour puis IMPLODE pour mettre à jour la colonne du client c'est :

    s'il y à une erreur en amont et que la requête SELECT ne trouve rien dans la colonne 'revendPaye' du client (alors que devrait s'y trouver "0") alors le tableau est vide et je ne peux donc pas remplacer monTableau[0] par la nouvelle valeur avant l'IMPLODE...

    Je vais faire un test dans ce sens

  6. #6
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Non tu fais erreur si je comprends ce que tu veux faire : ta transaction ne sortira pas en rollback si ton select ne trouve rien ou si ton update n'update rien ou encore si ton delete ne supprime rien. Ta transaction echouera si tes requetes sortent en erreur (au sens retour des fonction exec, execute, query...).

    Par contre, libre à toi de modifier à ta guise le comportement souhaité de tes transactions. Par exemple, si tu veux faire un rollback si ton insert n'a rien inséré en base et ce quelque soit l'issue de tes requetes suivantes, tu peux effectuer quelque chose de ce style :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $commit = true;
     
    // Début de tes requetes de transactions
     
    if($connexion-exec('INSERT...') === 0)
        $commit = false;
     
    //...
    // Fin de tes requetes de transactions
     
    ($commit == true) ? $transaction->commit() : $transaction->rollback();

    PDO::exec() retourne le nombre de lignes qui ont été modifiées ou effacées pour la requête SQL qui vous exécutez. Si aucune ligne n'est affectée, la fonction PDO::exec() retournera 0.
    Libre à toi donc d'utiliser les retours de fonctions PDO afin de moduler le comportement de tes transactions

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

Discussions similaires

  1. Insérer malgré une erreur Trigger
    Par mlaunay dans le forum PL/SQL
    Réponses: 8
    Dernier message: 04/12/2014, 14h29
  2. Continuer un job malgré une erreur
    Par jeanphi45 dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 17/06/2010, 15h04
  3. Réponses: 8
    Dernier message: 05/02/2008, 11h35
  4. MERGE - Pousuivre malgré une erreure
    Par ArCal dans le forum SQL
    Réponses: 3
    Dernier message: 17/01/2008, 18h12
  5. Réponses: 5
    Dernier message: 11/09/2007, 13h42

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