2011-02-11 4 views
2

Je table InnoDB lu par beaucoup de différentes instances (nuage)Ligne de verrouillage pour mettre à jour

daemon dans chaque instance prend 100 lignes à « faire des choses » de ce tableau, mais je ne veux pas 2 (ou plus) instances pour prendre les mêmes choses.

J'ai donc une colonne "status" ("todo", "doing", "done").

INSTANCE 1: Il faut 100 lignes où status = "todo" ... Ensuite, j'ai besoin de mettre à jour ces lignes au statut "doing", donc INSTANCE 2,3, .. x ne peut pas prendre les mêmes lignes .

Comment puis-je le faire? S'il vous plaît, je voudrais une solution sans table LOCKING WHOLE, mais en verrouillant juste les lignes (c'est parce que j'utilise innodb) ... J'ai beaucoup lu à ce sujet (LOCK SHARE MODE, POUR MISE À JOUR, COMMITs ...) mais je ne suis pas la bonne façon ...

Répondre

0

vous devez utiliser LOCK TABLES et fonctions UNLOCK TABLES pour ce faire:

http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html

+0

Cela gelerait l'autre démon. Peut-être que le DB prend une très courte période par rapport au traitement, mais il bloque tout le monde pendant un certain temps. Pour cela, le verrouillage au niveau des lignes est plus approprié. –

+0

Oui Marc B ... Je regarde ça ... le verrouillage de ligne, mais je ne sais pas comment le faire ... J'ai lu des tonnes de documentation, mais je ne trouve pas d'exemples, et je ne sais pas comment le faire exactement :( – FlamingMoe

+0

quelqu'un s'il vous plaît? – FlamingMoe

0

utiliser une transaction, puis SELECT ... FOR UPDATE lorsque vous lisez les enregistrements. De cette façon, les enregistrements que vous lisez sont verrouillés. Lorsque vous obtenez toutes les données mettre à jour les enregistrements à "faire" et COMMIT la transaction. Peut-être que ce qui vous manquait est l'utilisation d'une transaction, ou l'ordre correct des commandes. Voici un exemple de base:

BEGIN TRANSACTION; 
SELECT * FROM table WHERE STATUS = 'todo' FOR UPDATE; 

// Loop over results in code, save necessary data to array/list.. 

UPDATE table SET STATUS ='doing' WHERE ...; 
COMMIT; 

// process the data... 

UPDATE table SET STATUS ='done' WHERE ...; 
Questions connexes