2011-11-02 6 views
0

J'ai une table nommée events, qui contient des événements dans le jeu tels que la construction de bâtiments, la recherche, etc. Chaque événement a un timestamp indiquant quand il se termine. Moteur: innoDBTest de verrouillage MySQL fonctionne correctement

Chaque pageload, le programme exécute une recherche rapide du tableau events pour les lignes où timestamp est dans le passé (c'est-à-dire que l'événement a été terminé). Il sélectionne ces lignes puis les supprime afin que toutes les autres exécutions ne voient pas et ne traitent pas les mêmes événements. Ce qui m'inquiète, c'est ce qui se passerait si deux pagelods se produisaient de sorte que les deux lisent les mêmes lignes avant que l'une ou l'autre ait la possibilité de supprimer les lignes lues, et si un événement survient juste entre la sélection et supprimer.

Ce que je pense devrait fixer est:

SET @now=NOW(); 
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE 
DELETE FROM `events` WHERE `timestamp` < @now 

Mais je vais avoir quelques tests trouble. Comment pourrais-je tester si cela fonctionne ou non?

+0

Je pense que cela ne fonctionnera pas car les fonctions de temps comme 'NOW()' dans MySQL n'ont de précision que dans la seconde. Certaines charges de pages vont se passer pendant la même seconde avec une différence en millisecondes. – Xint0

+0

C'est bien, les événements eux-mêmes ne sont précis qu'à la seconde. Ce que je veux faire est de verrouiller les lignes sélectionnées, mais je veux aussi éviter que d'autres processus deviennent bloqués. –

Répondre

0

va répondre à ma propre question ici: p

Utilisez sleep() entre le select et delete, et ont deux appels en même temps.

Code final:

START TRANSACTION 
SET @now=NOW() 
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE 
-- SLEEP(5) 
DELETE FROM `events` WHERE `timestamp` < @now 

Résultats:

0,000: Démarrage transaction
0.001: exécution de la requête, retourné 5 lignes.
5.002: Suppression de 5 lignes.
5,008: Mettre fin à la transaction
===== Deuxième appel, a commencé quelques secondes après la première:
: 0.000 transaction À partir
2,562: requête exécutée, a donné 0 lignes.
2.562: 0 ligne supprimée.
2,562: Mettre fin à la transaction

C'est le sommeil. Sans le sommeil, les deux se terminent en moins de 0,002 secondes.

Questions connexes