2017-10-14 16 views
0

J'ai cherché de nombreuses questions similaires si je ne trouve pas que par intermittence renvoie 0SELECT LAST_INSERT_ID() retourne par intermittence 0

**** ***** EDIT

J'ai depuis essayé de tester avec une nouvelle table avec seulement deux colonnes, réduit le problème à environ 1 fois dans 50 fois retournant zéro.

J'ai tout à l'heure pu tester sur un serveur d'hébergement payé et je ne pouvais pas reproduire mon problème

Je suppose que la question de mon être spécifique à cet hébergeur.

Problème:

Lorsque vous essayez de récupérer le dernier ID Inséré sur une base par connexion, environ 4 fois sur dix je reçois un 0 à moi retourné.

Localhost, tout fonctionne bien sans problème. Le problème ne se pose que lorsque mon site est hébergé sur un serveur.

SELECT LAST_INSERT_ID() intermittently returns 0 

$PDOconnection->lastInsertId(); Always returns correct ID 

Je dois obtenir de manière fiable dernière inséré ID sur une base par connexion comme il est essentiel au processus de commande de mon site lors de la création d'un ordre d'achat dans la base de données.

Notes:

  • L'ID est auto-incrémentée
  • L'insert sql fonctionne toujours bien et la base de données montre une nouvelle entrée.
  • Commutation version PHP ne résout pas le problème
  • hôte Web J'utilise est un service d'hébergement gratuit J'utilise à des fins de test en direct
  • le temps de chargement est toujours similaire (500 - 750 ms pour le code Ci-dessous)

J'ai dépouillé le code entier vers le bas (comme ci-dessous) pour tester en simplicité. Le problème persiste

Je n'arrive pas à m'entraîner là où se situe mon problème. Exemple réel de résultats pour 10 requêtes d'affilée (simplement en actualisant simplement la page). J'ai fait écho aux résultats côte à côte.

checkout_id_0  $checkout_id_1 <---SELECT LAST_INSERT_ID() 

     16    16 
     17    17 
     18    0  // Returned 0 
     19    19 
     20    0  // Returned 0 
     21    0  // Returned 0 
     22    22 
     23    23 
     24    23  // Returned previous ID (happens 1/30 tries) 
     25    25 

config de connexion:

$PDOconnection = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8", $sql_username, $sql_password); 

// Set PDO error mode to exception 
$PDOconnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

// Set PDO Attribute to force native prepared statements 
$PDOconnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
+3

Toute raison pour laquelle vous ne pouvez pas utiliser la valeur retournée par 'lastInsertId'? Utilisez-vous 'mysqlnd'? (.. qui [prend en charge le pool de connexions, où une nouvelle connexion différente peut être utilisée pour chaque requête] (http://php.net/manual/fr/mysqlnd-ms.pooling.php)). – MatsLindh

+0

Utilisation de mysqlnd. J'étais sous l'impression que SELECT LAST_INSERT_ID() serait plus fiable dans un scénario de paiement e-comm étant que vous obtiendrez seulement l'ID retourné pour ce client spécifique? – user3796133

+0

@MatsLindh J'ai depuis essayé de tester avec une nouvelle table avec seulement deux colonnes et il a réduit le problème à environ 1 fois dans 50 fois rendant zéro. Je viens aussi de tester sur un serveur d'hébergement payant et je ne pouvais pas reproduire mon problème, je suppose que le problème sera spécifique à cet hébergeur. – user3796133

Répondre

0

Avez-vous essayé d'activer les connexions persistantes? Voir Connections and Connection management et Persistent Database Connections. Peut-être que ce serveur distant a des paramètres MySQL trop courts - wait_timeout et interactive_timeout ...

Les connexions persistantes ne sont pas fermées à la fin du script, mais sont mises en cache et demande re-lorsqu'un autre script une connexion en utilisant les mêmes informations d'identification. Le cache de connexion persistante vous permet d'éviter les frais généraux liés à l'établissement d'une nouvelle connexion chaque fois qu'un script doit communiquer avec une base de données, ce qui entraîne une application web plus rapide.

A noter également:

Si vous souhaitez utiliser des connexions persistantes, vous devez définir PDO :: ATTR_PERSISTENT dans le tableau des options du pilote transmis au constructeur PDO . Si vous définissez cet attribut avec PDO :: setAttribute() après l'instanciation de l'objet, le pilote n'utilisera pas les connexions persistantes .

Alors:

$PDOconnection = new PDO(
    "mysql:host=$servername;dbname=$dbname;charset=utf8" 
    , $sql_username 
    , $sql_password 
    , array(
     PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
     PDO::ATTR_EMULATE_PREPARES => false, 
     PDO::ATTR_PERSISTENT => true, 
    ) 
);