Juste pour vous donner un exemple: p>
J'ai un script PHP qui gère les votes des utilisateurs. P>
Lorsqu'un utilisateur vote, le script fait une requête pour vérifier si une personne a déjà voté pour le même identifiant / produit. Si personne n'a voté, il fait une autre requête et insérez l'ID dans une table des votes généraux et une autre pour insérer les données dans une table de vote par utilisateur. Et ce type de comportement est répété dans d'autres types de scripts. P>
La question est, si deux utilisateurs différents votaient simultanément, il est possible que les deux instances du code essaient d'insérer un nouvel ID (ou un type de requête similaire) qui donnera une erreur ?? P>
Si oui, comment j'empêche cela de se produire? P>
merci? p>
4 Réponses :
Ceci quand le modèle singleton est utile. Il garantit qu'un code n'est exécuté que par un processus à un instant. P>
http://fr.wikipedia.org/wiki/singleton_pattern p>
Vous devez créer une classe Singleton pour l'accès à la base de données, cela vous empêchera du type d'erreur que vous décrivez. P>
acclamations. p>
Mauvaise idée, et cela ne résoudra pas le problème de l'accès concomitant dB dans PHP.
Une classe singleton (même dans un environnement de Java typique) ne résoudra pas le problème. Cela signifie simplement qu'il ne peut y avoir qu'un seul instance, mais cela peut être accédé par plusieurs threads en parallèle.
Merci pour l'explication :)
La question est, si deux différents Les utilisateurs vote simultanément son possible que les deux cas de la code essayer d'insérer un nouvel identifiant (ou certains type similaire de requête) qui donnera une erreur ?? p> blockQuote>
Oui, en général c'est possible. Ceci est un exemple de problème très courant dans les systèmes concurrents, appelé un condition de course . p>
Éviter que cela peut être plutôt délicat, mais en général, vous devez vous assurer que les opérations ne peuvent pas interlisser de la manière dont vous décrivez, par exemple. En verrouillant la base de données pendant un moment. p>
Il y a plusieurs solutions pratiques à cela, toutes avec leurs propres avantages et risques (par exemple, serrures mortes). Voir l'article Wikipedia pour une discussion et d'autres pointeurs à l'information. P>
La question est, si deux utilisateurs différents vote simultanément, il est possible que les deux instances de la Code Essayez d'insérer un nouvel identifiant (ou un type de requête similaire) qui donnera un erro p>
Oui, vous pourriez vous retrouver avec deux questions faisant l'insert. En fonction des contraintes de la table, l'un d'entre eux générera une erreur, ou vous vous retrouverez avec deux lignes de votre base de données. P>
Vous pouvez résoudre ceci, je crois, avec une application de blocage; par exemple. Si vous devez ajouter un vote au produit avec ID TheProductid: (pseudo code) p>
xxx pré> une autre info ici p>
MySQL offre une autre solution également, cela pourrait être applicable ici, Insérez sur duplicata P>
xxx pré> si votre table de votes a une clé unique sur la colonne ID de produit, ce sera Faites un insert si le produit spécifique n'existe pas, sinon il effectuera une mise à jour, où elle incrémente la colonne Nombre devotes par 1 P>
Vous pouvez probablement éviter beaucoup de ceci si vous avez créé une ligne dans les votes Tableau en même temps que vous avez ajouté le produit à la base de données. De cette façon, vous pourriez être sûr qu'il y a toujours une ligne pour votre produit, et émettez simplement une mise à jour sur cette ligne. P> blockQuote>
Les transactions existent exactement pour résoudre ce problème. En utilisant les transactions telles que ceci, vous garantissez qu'aucune requête ne peut jamais voir un état intermédiaire dans la base de données.
+1 pour sur la touche en double code>. Opération atomique> Verrouillage manuel.
Le moyen le plus simple: Si le vote ne se produit pas de plusieurs fois par seconde, ce qui précède devrait être suffisant. p> Tables Innodb propose des transactions, ce qui pourrait être utile ici aussi. D'autres ont déjà commenté, donc je n'entrerai pas en détail. P> Vous pouvez également le résoudre au niveau du code via en utilisant une sorte de mémoire partagée mutex qui désactive l'exécution simultanée de cette section de Code PHP. P> p>
Cela pourrait aider à montrer votre structure de table (noms de table / colonne)
Je donne juste un exemple mais pour vous aider à sortir: Product_votes Table dispose d'un produit productible, de votes_count et d'une colonne TOTAL_VOTES_VALUE. La table user_product_votes contient un ID utilisateur, un produit producteur et une colonne user_vote.
La seule raison pour laquelle je demande est que, dans cet exemple, il semble qu'il serait préférable de réorganiser votre structure logique et de table afin que les inserts simultanés ne comptent pas au lieu d'essayer de les empêcher. Demandez-vous une question générale ou avez-vous besoin de résoudre le problème spécifique dans votre exemple?