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 PDO inactive [PDO]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Février 2007
    Messages
    248
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 248
    Par défaut Transaction PDO inactive
    Bonjour,

    J'utilise PDO depuis un petit moment et je souhaiterai maintenant utiliser les transactions...

    J'initialise une transaction, effectue l'ensemble de mes traitements, lorsque je lance le commit() ou le rollback, j'ai l'exception avec le message suivant :'There is no active transaction'

    Je vous ai mis le code correspondant....
    (j'ai supprimé pas mal de ligne inutile et il ne s'agit que d'une portion d'un script, le nombre de } peut être erroné...)

    Merci d'avance !!!

    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
    73
     
    // Debut de la transaction PDO 
    Factory::get( BDD_DRIVER ) -> beginTransaction() ;
     
    // Preparation des requetes PDO
    $preSelect 	= "SELECT note_valeur FROM etudiants_notes 
    			     WHERE note_etu_numero = :etu_numero 
    			     AND note_enseignement = '".$this -> idEns."' 
    			     AND note_epreuve = $epreuveId " ;
     
    $preUpdate	= "UPDATE etudiants_notes 
    			    SET note_valeur = :note
    			    WHERE note_etu_numero = :etu_numero 
    			    AND note_enseignement = '".$this -> idEns."' 
    			    AND note_epreuve = '$epreuveId' " ;
     
    $preInsert	= "INSERT INTO etudiants_notes 
    		    ( note_etu_numero , note_enseignement , note_epreuve , note_valeur )
    	            VALUES
    		    ( :etu_numero , '".$this -> idEns."' , '$epreuveId' , :note ) " ;
     
    $stmtSelect = Factory::get( BDD_DRIVER ) -> prepare( $preSelect ) ;
    $stmtUpdate = Factory::get( BDD_DRIVER ) -> prepare( $preUpdate ) ;
    $stmtInsert = Factory::get( BDD_DRIVER ) -> prepare( $preInsert ) ;
     
    // Ouverture du fichier en lecture
    ini_set( 'auto_detect_line_endings' , TRUE ) ;
    $csvContent = fopen( 'imports/'.$destinationName, 'r' ) ;
     
    // Traitement des donnees du fichier CSV
    while ( ( $data = fgetcsv( $csvContent, 20, ";" ) ) !== FALSE ) 
    {
        $this -> statistiques['nbNote']++ ;
     
        // Preparation des donnees 
        $numEtu = $data[0] ;
        $noteEtu = $data[1] ;
        $noteEtu = str_replace(',', '.', $noteEtu ) ; 
     
       // J'ai supprime les verifications sur le contenu
     
        if ( $this -> error == NULL )
        {
            // Verification si la note est deja saisie
    	$stmtSelect -> bindParam( ':etu_numero', $numEtu );
    	$stmtSelect -> execute();
    	$etuData	= $stmtSelect -> fetchAll( PDO::FETCH_ASSOC );
    	$etuOldNote = @$etuData[0]['note_valeur'] ;
    	$etuNb		= $stmtSelect -> rowCount() ;
     
    	// Insertion de la note
    	if ( $etuNb < 1 )
    	{
    		$stmtInsert -> bindParam( ':etu_numero', $numEtu );	
    		$stmtInsert -> bindParam( ':note', $noteEtu );
    		$stmtInsert -> execute() ;
    	}
    	// Mise a jour de la note
    	elseif ( $etuNb == 1 && $etuOldNote == '99.00' )
    	{
    		$stmtUpdate -> bindParam( ':etu_numero' , $numEtu ) ;
    		$stmtUpdate -> bindParam( ':note' , $noteEtu ) ;
    		$stmtUpdate -> execute();
    	}
     
            Factory::get( BDD_DRIVER ) -> commit() ;
        }
        else
        {
             Factory::get( BDD_DRIVER ) -> rollBack();
        }
    }
    }

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 49
    Par défaut
    Bonjour,

    Ça serait intéressant d'avoir le code de Factory.

    Le get () renvoie à chaque fois un objet basé sur la même connexion ouverte ?

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Février 2007
    Messages
    248
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 248
    Par défaut
    C'est effectivement toujours la même connexion...

    Voici le code de la fonction get de factory...

    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
    class Factory 
    {
        static public function get( $sObject) 
        {
            if ( ! class_exists( $sObject)) 
            {
                if ( ! file_exists( $sFile = dirname( __FILE__).'/class.'.$sObject.'.php')) 
                {
                     throw new FactoryException( 'Driver introuvable.');
                }
                require $sFile;
                if ( ! class_exists( $sObject)) 
                {
                   throw new FactoryException( 'Driver mal implémenté');
                }
            }
            $oDriver = call_user_func( array( $sObject, 'getInstance'));
     
            return $oDriver;
        }

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 49
    Par défaut
    Ok.

    Je relis attentivement ton code.

    Ton commit et ton rollback sont dans un while, et ton beginTransaction est avant le while.

    Donc si tu itères au moins 2 fois, et bien la 2ème fois il n'y a plus de transaction ouverte...

    Par ailleurs, tu devrais garder ton objet dans une variable, plutôt que d'appeler le factory à tire-larigot. Même si le code du get n'a pas l'air très gourmand. D'autre part si tu décides de changer de manière de récupérer ta connexion, tu vas avoir un paquet de Factory::get... à rechercher / remplacer.

    [edit] Je ne suis toujours pas sur à 100% que tu as la même connexion à chaque fois, et ça n'est pas le code de Factory qui le prouve, la question est reportée sur la classe qui fournit le getInstance.
    Normalement, dans le pattern Factory, on a une instance différente chaque fois...

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Février 2007
    Messages
    248
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 248
    Par défaut
    Ton commit et ton rollback sont dans un while, et ton beginTransaction est avant le while.
    Donc si tu itères au moins 2 fois, et bien la 2ème fois il n'y a plus de transaction ouverte...
    Merci bien pandrogynik, j'y crois pas d'être passé à coté de cette erreur !!

    Par ailleurs, tu devrais garder ton objet dans une variable, plutôt que d'appeler le factory à tire-larigot. Même si le code du get n'a pas l'air très gourmand. D'autre part si tu décides de changer de manière de récupérer ta connexion, tu vas avoir un paquet de Factory::get... à rechercher / remplacer.
    Je t'avoue que j'ai implémenté un factory sans maitriser vraiment la problématique... En tout cas, j'ai suivi ton conseil et j'ai placé l'objet dans un variable dans mon constructeur de class.

    Je ne suis pas toujours sur à 100% que tu as la même connexion à chaque fois, et ça n'est pas le code de Factory qui le prouve, la question est reportée sur la classe qui fournit le getInstance.
    Normalement, dans le pattern Factory, on a une instance différente chaque fois...
    Ah ben là, ce qui m'embête c'est que je renvoie à ma remarque précédente... j'aurai probablement mieux fait d'éviter d'utiliser factory que je ne maitrise pas ! Il faudrait vraiment que je me penche sur la question...

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 49
    Par défaut
    L'idée d'une factory (entre autre, ça n'est pas une définition exhaustive des enjeux de ce pattern), c'est souvent d'abstraire un choix de classe spécifique.

    C'est fréquent pour les classes de connexion BDD, on te propose d'identifier sous la forme d'un paramètre simple le driver utilisé ou le SGBD sollicité, ce qui permet une maintenance très simple en cas de changement de système, plutôt que d'avoir codé avec un "new" sur une classe du genre Driver_Pdo_JeNeSaisQuoi_Bidule_SQL_103b et de devoir changer pour MySQL_SuperPower_MegaConnector_Beta13.

    En revanche, il n'y est pas, en général ,question d'unicité d'instance. L'unicité nous amène à songer au pattern singleton, qui répond à des problématiques toutes autres. Il ne faut pas se laisser tromper par la méthode "getInstance" qui est par "tradition" le nom donné à la méthode statique permettant précisément de récupérer un singleton.

    Ton Factory ne présente pas de problème notable, et récupérer une fois seulement l'objet dans une variable sera finalement la meilleure garantie que tu causes toujours à la même connexion.

    Bonne chance pour la suite.

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

Discussions similaires

  1. [PDO] Transaction PDO mysql
    Par chat de nuit dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 25/10/2011, 16h33
  2. [MySQL] php pdo Transactions
    Par watibou dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 03/09/2010, 14h59
  3. [PDO] PDO et transactions
    Par Madfrix dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 10/05/2010, 08h21
  4. [PDO] PDO/MYSQL: les transactions?
    Par Helfima dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 21/04/2009, 10h04
  5. Apropos des Transactions au sein d'un Stored Procedure
    Par Sarbacane dans le forum Connexion aux bases de données
    Réponses: 6
    Dernier message: 16/11/2004, 08h21

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