2009-10-07 9 views
0

Disons que vous avez une table avec des numéros gagnants. N'importe lequel de ces nombres est destiné à être seulement "gagné" par une personne. Comment puis-je empêcher 2 demandes Web simultanées qui soumettent les mêmes numéros à la fois vérifier et voir que les numéros sont toujours disponibles et ensuite donner le prix à tous les deux avant que le numéro est marqué comme n'étant plus disponible.Comment empêcher plusieurs requêtes Web de traiter les mêmes enregistrements?

La solution gagnante dans this question me semble être ce que je pensais faire, car elle peut également être appliquée dans la plupart des plates-formes de base de données.

Existe-t-il un autre modèle commun qui peut être appliqué à cela?

Répondre

6

Ces nombres sont générés de manière aléatoire ou quelque chose?

Je reposerait sur la sémantique transactionnelle dans la base de données elle-même: créer une table avec deux colonnes, le nombre et revendiqué, et d'utiliser une seule mise à jour:

UPDATE winners SET claimed=1 WHERE claimed=0 AND [email protected]; 

puis vérifier que le nombre de lignes affectées.

+0

vous avez besoin d'une transaction comme ironfroggy dit. Sinon, vous pourriez avoir une autre requête pour obtenir le numéro entre le select et la mise à jour. –

+1

Il n'y a pas de sélection et de mise à jour - juste une seule UPDATE, qui est une transaction implicite. –

+1

Juste curieux si vous connaissez la réponse: Si vous utilisez un SE sans support de transaction (par exemple MyIsam), cela serait-il encore atomique? – troelskn

1

Utiliser les transactions. Vous ne devriez jamais avoir plusieurs threads ou processus changeant les mêmes données sans verrous transactionnels et n'importe quelle base de données décente soutient des transactions aujourd'hui. Commencez la transaction, "attrapez" le numéro gagnant, puis validez. Un autre thread serait verrouillé jusqu'à la validation, et n'obtiendrait sa chance qu'après la mise à jour des enregistrements, quand il pourrait voir son déjà là.

0

Une solution non basée sur une base de données peut être que le client effectue une requête asynchrone, puis envoie la requête dans une file d'attente FIFO pour contrôler les requêtes afin qu'une seule requête à la fois soit évaluée. Ensuite, répondez au client lorsque l'évaluation est terminée. L'avantage ici serait que sous forte charge, l'interface utilisateur ne serait pas figée là où il y aurait un verrouillage transactionnel au niveau de la base de données.

Questions connexes