Fonctionnement de MySQL via php

p4bl0

Membre expert
Club iGen
12 Juillet 2004
4 772
423
34
$PWD
p4bl0.net
Hello :)

Le titre est pas bien clair mais je ne sais pas comment l'expliquer simplement.
Alors voici un exemple du cas qui me pose problème.

On a une base de données MySQL avec une table qui contient des stocks (on s'en fou de quoi).
Il reste 1 seul exemplaire d'un produit.

Il y a deux personnes qui l'ajoutent dans leur panier et qui vont payer au même moment.
À partir du moment ou le visiteur entreprend l'action de payer, on décrémente la valeur du champ du nombre d'exemplaire du produit.
Le problème là c'est qu'ils sont deux en même temps et que je ne sais pas comment MySQL se comporte.

Solution 1:
Les requêtes sont exécutées l'une après l'autre, à ce moment là il n'y a pas de problème parce que la seconde requête (toutes en fait) n'a qu'à vérifier si le produit est toujours dispo à chaque étape du paiement.

Solution 2:
MySQL gère les requêtes en leur allouant un certains temps à chacune. Dans ce cas il y a peut-être un problème :
Par exemple imaginons que chacune des deux requêtes mettent une seconde à s'exécuter (c'est un exemple hein) et que MySQL alloue des plages de temps d'une demie secondes.
ça pourrait faire un truc du genre :
0.0 s
requête 1 début
0.5 s
requête 2 début
1.0 s
requête 1 fin
1.5 s
requête 2 fin

Du coup la requête 2 pourrait croire qu'il y a encore du stock alors qu'en fait il n'y en a plus :hein:

(Je sais pas si je suis très clair désolé.)

Ou alors ça fonctionne encore autrement ?

Si jamais c'est comme je le dis dans "Solution 2", est ce qu'utiliser des transactions avec une table InnoDB règlerai le problème ? Je sais que c'est fait pour ce genre de truc, mais malgré tout c'est assez instantané les requêtes MySQL depuis PHP, donc je ne sais pas si ça marche/suffit.

Sinon peut-être qu'il suffit de bloquer le temps d'exécution d'une requête l'accès à la table par d'autres ? Ça risque pas de créer des conflits ou autre bêtises du genre ?


Merci d'avoir lu jusque là et si vous avez compris mon problème c'est déjà coule, si vous le résolvez c'est carrément coule :p :cool:
 
On est dans ton cas 1. Si de chaque côté tu n'as qu'une seule requête qui fait la vérif et la mise à jour, tu n'auras pas de problème.

Si tu devais enchaîne des traitements, genre :
1) vérifier la valeur en base
2) effectuer d'autres traitements (validation de la commande, mise à jour d'autres tables, ...)
3) mise à jour de la valeur
là il faudrait utiliser les transactions :

1)START TRANSACTION
2)SELECT .... FOR UPDATE (vérouille la ligne)
3) tes traitements
4) COMMIT (ou ROLLBACK si erreur)
Attention à ce qu'il y ait forcément un commit ou un rollback, pour que le verrou sur la ligne reste le moins longtemps possible.
 
  • J’aime
Réactions: p4bl0