JeuWeb - Crée ton jeu par navigateur
[PHP] Pour quelles raisons un INSERT peut être executé 2 fois ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [PHP] Pour quelles raisons un INSERT peut être executé 2 fois ? (/showthread.php?tid=5660)

Pages : 1 2 3 4


[PHP] Pour quelles raisons un INSERT peut être executé 2 fois ? - php_addict - 22-08-2011

bonjour

voici une question insolite:

Pour quelles raisons un INSERT d'une requête SQL peut être exécuté 2 fois ? car par moment j'ai la quasi certitude qu'une requête s’exécute deux fois alors que je l'ai mise dans une transaction:


$dbb->beginTransaction();

$query = "INSERT INTO liste ( a,b,c) VALUES ( :a, :b, :c)";
$result = $dbb->prepare("$query");
$result->execute(array(':a' => $a, ':b' => $b,':c' => $c));

$id = $db->lastInsertId();

// et là une autre requete se servant de $id

$dbb->commit();

(c'est un exemple mais ma requete ressemble trait pour trait à celle ci dessus)

et à priori ma connexion à la dbb n'est pas persistante:


$this->dbh = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$nom_bd, $utilisateur, $mot_passe, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

donc je me demande si il y a des raisons pour qu'une requête SQL peut être exécutée 2 fois (sans que cela soit voulue?

pages web lente à charger?
script lent à s’exécuter?
plusieurs pages ouvertes dans le même navigateur ?
A cause de ma connexion non persistante ?

merci de m'avoir lu


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - niahoo - 22-08-2011

Y a quand même 99% de chances que ce soit ta fonction qui est appellée 2 fois


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - php_addict - 22-08-2011

bein...c'est pas certain, cette fonction n'est présente qu'une fois dans tout mes scripts et il est impossible de double-cliquer sur le lien qui lance cette fonction (intervalle minimum de 1 seconde).

et bien que cette fonction ne puisse etre appelée par un joueur 2 fois de suite elle s’exécute quand meme au même timestamp (lors de l'INSERT j'insert le timestamp et ils sont identiques)

je m'arrache les cheveux
:emoticone_d_arrachage_de_cheveux:


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - niahoo - 22-08-2011

ben tu peux déjà remplacer l'appel de ta fonction par un "echo 'salut';" ou bien un log dans un fichier ou bien t'envoyer un mail.


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - php_addict - 22-08-2011

oui mais le hic c'est que cela arrive 1 fois sur 1000 (au pif)


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - niahoo - 22-08-2011

ah mais c'est pas un détail ça Smile

Un truc qui a rien a voir mais dans ton array, il ne faut pas mettre les ':' devant le nom des clés il me semble.

Il ne te reste qu'a détecter le moment ou ça arrive (par exemple en comparant le count() des lignes avant et après l'appel de ton script) et quand ça arrive, balancer un exception puis en afficher la trace


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - php_addict - 23-08-2011

bon j'ai fait des tests dans tout les sens, exécution du script à la milliseconde pres dans plus de 10 fenêtre de navigateurs.

rien n'y fait, je n'arrive pas a reproduire ce bug, est ce que le cache d'opcode APC peut déconner ?

j'ai un joueur qui a cliqué sur "construire un batiment" et l'INSERT c'est exécuté 2 fois, ce qui est pourtant impossible car:

- il n'avais pas assez de sous pour le 2eme INSERT (le script vérifie si il a assez de sous)
- qu'il ne peut pas construire un bâtiment en moins d'une seconde (vérification timestamp)
- il est impossible de construire un bâtiment de même niveau sur le même slot (augmentation du level du bâtiment)

Honnêtement je crois que l'INSERT s'est exécuté 2 fois sans mon consentement.

Avez vous eu vent d'une telle chose? j'ai trouvé ceci, mais ca ne correspond pas franchement à mon soucis: LIEN


niahoo a écrit :Un truc qui a rien a voir mais dans ton array, il ne faut pas mettre les ':' devant le nom des clés il me semble.

effectivement ca marche sans les ':' , il faut vraiment ne pas utiliser les ':' dans l'array de execute ?


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - Akira777 - 23-08-2011

Je crois que l'on a le même problème. Cela arrive qu'un joueur quand il laisse un commentaire sur une news par exemple, le commentaire apparaisse deux fois. Me suis demandé si c'était parceque le bonhomme double-cliquait sur le bouton "Envoyer" mais j'ai jamais réussi à le faire...

Méthode barbare pour corriger le problème, une file d'attente dans une classe abstraite PDO, avec une routine qui passe pour supprimer les doublons xD Nan je plaisante, c'est vraiment laid ça !


RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - Sephi-Chan - 23-08-2011

Si c'est bien un problème de double-click, il y a des solutions simples :
  • Côté client, désactiver (même temporairement) le bouton en Javascript une fois le formulaire soumis.
  • Côté serveur, stocker en session la date de dernière soumission de formulaire et contrôler que cette date n'est pas trop récente.



RE: Pour quelles raisons un INSERT peut être executé 2 fois ? - php_addict - 23-08-2011

- le hic c'est que j'ai fait ce que ce n'est pas un double click (je verifie cote serveur un timestamp stocké en session)
- j'ai controler 100 fois depuis hier, et il est impossible que cela est eu lieu

et pourtant j'ai un INSERT dans ma base de donné qui s'est exécuté 2 fois au même timestamp (généré par le même joueur)

je reste persuadé que mysql à exécuté 2 fois le même requête, je vais essayé de trouver ca dans mes logs serveur mais ca va etre galère...