Bonjour à tous,
J'écris en PHP un jeu d'instant gagnant dans lequel il est possible de gagner une fois toutes les demi heures. Pour ce faire, je vérifie dans ma table "winnertable" l'heure du dernier gain (SELECT), et si cela remonte à plus d'une demi-heure, j'insère le nouveau gagnant (INSERT).
Ma table winnertable est sous InnoDB.
Cette partie de mon script est appelée par chaque client et décide si il a gagné ou non. La réponse doit lui être affichée à la page suivante, donc pas possible de mettre en place un CRON.
Voici ce que cela donne en pseudo code (version PHP ici : http://pastebin.com/dn1txbYm) :
SELECT date FROM winnertable ORDER BY id DESC
Si (la date actuelle) - (le champ "date" de la première ligne renvoyée par la requête précédente) > une demi-heure alors :
INSERT INTO winnertable (id_main, date) VALUES ('".$_SESSION['id']."', '".$currentTime."')
Je pense que cette solution n'est pas bonne car si le script est lu par de multiples clients au même moment, des SELECT risquent d'être exécutés au même moment et plusieurs clients risquent alors de gagner à chaque demi-heure.
J'ai cherché quelques solutions :
- Utiliser un LOCK TABLE : mais j'ignore le coût en termes de performances. De plus, j'ai lu que c'était déconseillé de le faire sur une table InnoDB. Je peux cependant passer ma table en MyIsam si c'est la solution.
- Rendre mon champ "date" UNIQUE en base, pour éviter de multiples insertions de la même date. Mais je ne suis pas sur que ce soit fiable à 100%.
- Utiliser les transactions d'InnoDB, mais je ne suis pas certain du tout que les transactions empêchent les accès concurrents en lecture ou en écriture. Sur le web beaucoup de ressources parlent du SELECT FOR UPDATE, mais en l'occurrence, je fais plutot un SELECT puis INSERT en fonction, donc je ne m'y retrouve pas.
Qu'en pensez-vous ?
Merci !
Partager