2009-06-28 9 views
0

je fais face le problème suivantproblème de requêtes simultanées dans MySQL

function book($memberid, $classid){ 
if (!book){ 
// update the db and change the book variable to true 
} 
} 

Mon problème est de 2 demandes présentées en même temps. La première requête passe la ligne if (! Book) {mais pas encore le db. Et en même temps, la deuxième requête exécute la même fonction et passe également la ligne if (! Book) {. Par conséquent, le résultat est faux.

Je veux savoir comment résoudre ce problème de concurrence. Verrouiller le db? Mais j'ai peur que cela affecte la performance.

Répondre

1

Pourquoi avez-vous besoin de cette variable? La manière standard de résoudre les problèmes de simultanéité lors de la mise à jour des bases de données est de permettre à la base de données de la gérer au moyen de transactions (ce qui affectera les performances dans certains cas).

Je voudrais voir ce qui se passe dans la clause if (! Book).

EDIT: Pourquoi ne modifiez-vous pas le db pour que la combinaison (personne, classe) soit une clé unique? De cette façon, physiquement, vous ne pouvez pas insérer deux fois la même valeur dans la table. Je prends toujours des suppositions sauvages parce que cela dépend de la structure de la base de données. MySQL a aussi une syntaxe spéciale pour faire une insertion conditionnelle qui conviendrait ici. Cochez cette case url.

+0

si (! Book) sélectionne simplement à partir de la base de données pour voir si la personne réserve une classe. Si la personne ne réserve pas la classe auparavant, elle peut alors réserver la classe. Sinon, il n'est pas autorisé à réserver à nouveau le cours. – Billy

+0

Pourquoi ne changez-vous pas le db pour que la combinaison (personne, classe) soit une clé unique? De cette façon, physiquement, vous ne pouvez pas insérer deux fois la même valeur dans la table. Je prends toujours des suppositions sauvages parce que cela dépend de la structure de la base de données. MySQL a aussi une syntaxe spéciale pour faire une insertion conditionnelle qui conviendrait ici. Vérifiez http://forums.mysql.com/read.php?97,164551,164575#msg-164575 –

0

Si vous create an unique index(person,class) vous pouvez simplement essayer d'insérer le nouvel enregistrement sans les précédents tets. S'il y a déjà un autre enregistrement avec les mêmes valeurs (personne, classe) le nouveau dossier sera rejeté et MySQL soulève une "duplicate key" error qui peut être manié de façon appropriée par votre script:

if (1062===mysql_errno()) { 
    echo "you've already made a reservation for this lecture."; 
}

0

Peut-on utiliser

UPDATE x SET y WHERE z 

alors simplement check affected rows pour voir si quelque chose a changé? De cette façon, MYSQL effectue à la fois la vérification et la modification des données réelles en une seule transaction atomique fluide pour vous sans problèmes de concurrence. (Je me base sur le fait que vous utilisez le mot "update" et non "insert" dans votre Q, si c'est un insert cette approche ne fonctionnera pas mais VolkerK's)

Si vous devez vraiment vérifier par SELECT puis écrivez UPDATE comme 2 instructions distinctes, puis les transactions sont la seule façon de procéder. Vous mentionnez le verrouillage de la base de données - notez que ce n'est pas la seule option qui s'offre à vous. Si vous utilisez des tables InnoDB, vous pouvez utiliser différents niveaux.

+0

note: plus de détails aiderait; la structure exacte de SQL et de table – James

Questions connexes