Блокировка строки для обновления

У меня есть таблица innodb, читаемая множеством разных экземпляров (облако)

Демон в каждом экземпляре занимает 100 строк, чтобы «делать что-то» с этой таблицей, но я не хочу, чтобы 2 (или более) экземпляра выполняли одни и те же действия.

Итак, у меня есть столбец «статус» («дело», «делаю», «сделано»).

ЭКЗЕМПЛЯР 1: требуется 100 строк, где статус = "todo"... Затем мне нужно как можно скорее ОБНОВИТЬ эти строки до статуса "выполняется", поэтому ИНСТАНЦИЯ 2,3,..x не может принимать одни и те же строки.

Как мне это сделать ?

Пожалуйста, мне нужно решение без БЛОКИРОВКИ ВСЕЙ таблицы, но с блокировкой только строк (это потому, что я использую innodb) ... Я много читал об этом (LOCK SHARE MODE, FOR UPDATE, COMMITs ...), но я делаю не попасть в нужное русло...


person FlamingMoe    schedule 11.02.2011    source источник


Ответы (2)


Для этого вы должны использовать функции LOCK TABLES и UNLOCK TABLES:

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

person user470714    schedule 11.02.2011
comment
Это заморозило бы другого демона. Возможно, работа с БД занимает очень короткое время по сравнению с обработкой, но она блокирует всех на какое-то время. Для этого больше подходит блокировка на уровне строк. - person Marc B; 11.02.2011
comment
Да, Марк Б... Я ищу это... блокировку строк, но не знаю, как это сделать... Я перечитал тонны документации, но примеров не нашел, и не знаю, как сделать это точно :( - person FlamingMoe; 11.02.2011

используйте транзакцию, а затем SELECT ... FOR UPDATE при чтении записей. Таким образом записи, которые вы читаете, блокируются. Когда вы получите все данные, обновите записи на «выполнение» и COMMIT транзакцию. Возможно, вам не хватало использования транзакции или правильного порядка команд. Вот простой пример:

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 ...;
person Galz    schedule 14.02.2011