17-02-2010, 08:53 PM
Je reviens de nouveau vous poser une question, la dernière, enfin j'espère (depuis le temps que je dis que ça va être la dernière...). Cette fois-ci c'est sûrement la plus compliquée de toutes.
Comment faire pour éviter qu'un évènement impliquant deux joueurs ne soit exécuté deux fois ?
J'imagine le scénario-catastrophe suivant :
0. Un combat est programmé entre A et B
1. A se connecte, la liste des évènements est récupérée et le calcul du combat démarre
2. Pendant ce temps, B se connecte, récupère la liste des évènements et voit aussi qu'il y a un combat à traiter.
3. Le calcul du combat est terminé chez A, l'évènement correctement traité est effacé. Tout va bien.
4. Le calcul du combat est terminé chez B. ON tente de supprimer l'évènement une deuxième fois mais rien ne se passe et pourtant tout va bien. Alerte au bug ! le combat a eu lieu deux fois !
JE vois bien une solution bourrin, mais il doit y avoir plus simple pour prévenir de ce genre de bug.
Inutile de rappeler qu'une requête dans une boucle est un véritable auto-suicide propre à soi-même de la mort qui tue conduisant à un terrible cataclysme inéluctable et apocaliptique pour les performances.
De plus, je ne vois pas en quoi les transactions règleraient le problème. Parce qu'on pourrait avoir ce scénario-là :
1. A se connecte et commence une transaction
B. A récupère la liste des évènements et voit le combat
3. A traite le combat
4. A sauvegarde
5. B se connecte et commence une transaction. Pas de problème vu que les deux connexions à MySQL sont indépendantes
6. B récupère la liste des évènements. A n'a pas encore commit donc B voit toujours le combat dans la liste des évènements récupérée
7. A commit
8. B traite le combat
9. B sauvegarde
10. B commit. Résultat : le combat a été effectué deux fois quand même.
Ou alors est-ce que je suis paranoïaque et les scénarios que j'expose ne peuvent techniquement jamais arriver ?
Comment faire pour éviter qu'un évènement impliquant deux joueurs ne soit exécuté deux fois ?
J'imagine le scénario-catastrophe suivant :
0. Un combat est programmé entre A et B
1. A se connecte, la liste des évènements est récupérée et le calcul du combat démarre
2. Pendant ce temps, B se connecte, récupère la liste des évènements et voit aussi qu'il y a un combat à traiter.
3. Le calcul du combat est terminé chez A, l'évènement correctement traité est effacé. Tout va bien.
4. Le calcul du combat est terminé chez B. ON tente de supprimer l'évènement une deuxième fois mais rien ne se passe et pourtant tout va bien. Alerte au bug ! le combat a eu lieu deux fois !
JE vois bien une solution bourrin, mais il doit y avoir plus simple pour prévenir de ce genre de bug.
Inutile de rappeler qu'une requête dans une boucle est un véritable auto-suicide propre à soi-même de la mort qui tue conduisant à un terrible cataclysme inéluctable et apocaliptique pour les performances.
Code :
while ($db->value('select @flag')>0) usleep(10); // carton rouge
$db->exec('set @flag = 1');
// traitements à effectuer
$db->exec('set @flag = 0');
De plus, je ne vois pas en quoi les transactions règleraient le problème. Parce qu'on pourrait avoir ce scénario-là :
1. A se connecte et commence une transaction
B. A récupère la liste des évènements et voit le combat
3. A traite le combat
4. A sauvegarde
5. B se connecte et commence une transaction. Pas de problème vu que les deux connexions à MySQL sont indépendantes
6. B récupère la liste des évènements. A n'a pas encore commit donc B voit toujours le combat dans la liste des évènements récupérée
7. A commit
8. B traite le combat
9. B sauvegarde
10. B commit. Résultat : le combat a été effectué deux fois quand même.
Ou alors est-ce que je suis paranoïaque et les scénarios que j'expose ne peuvent techniquement jamais arriver ?
html, javascript, blagues, midi, etc. => http://quentinc.net/