Блокировка строки для обновления статуса - PullRequest
2 голосов
/ 11 февраля 2011

У меня есть таблица «команд для выполнения» со статусом («toprocess», «обработка», «выполнено»)

У меня есть несколько экземпляров (amazon ec2) с демоном, запрашивающим «команды»to do ".

Демон запрашивает строки со статусом" toprocess ", затем обрабатывает их и в конце каждого цикла меняет статус на" done ".

Дело в том, чточто перед запуском этого цикла мне нужно изменить все строки 'toprocess' на статус 'обработка', чтобы другие экземпляры не брали те же строки во избежание конфликта.

Я читал о блокировках строк innodb,но я не очень хорошо понимаю их ...

SELECT * из команд, где status = 'toprocess', тогда мне нужно взять идентификаторы этих результатов и обновить статус до 'processing', блокируя эти строкипока они не будут обновлены.

Как я могу это сделать?

Спасибо

Ответы [ 3 ]

3 голосов
/ 13 февраля 2011

Вы используете транзакцию и считываете данные с помощью FOR UPDATE, что блокирует другие операции выбора, включающие FOR UPDATE в выбранных строках

begin transaction;
 select * from commands where status = 'toprocess' for update;
 for each row in the result:
  add the data to an array/list for processing later. 
  update commands set status='processing' where id = row.id;

 commit;

process all the data

Прочтите немного об ДЛЯ ОБНОВЛЕНИЯ и InnoDB уровнях изоляции .

1 голос
/ 13 февраля 2011

Возможное (но не очень элегантное) решение может заключаться в том, чтобы сначала ОБНОВИТЬ запись, а затем прочитать ее данные:

У каждого демона будет уникальный идентификатор, а в таблице будет новый столбец с именем «владелец».'для этого идентификатора.Тогда демон будет запускать что-то вроде «UPDATE table SET status =« processing », owner =« theDeamonId », где status =« toprocess »... LIMIT 1»

Во время выполнения обновления строка заблокирована, поэтомуникакой другой Деймон не может это прочитать.После обновления эта строка принадлежит определенному демону, затем он может запустить SELECT, чтобы получить все необходимые данные из этой строки (WHERE status = 'processing' AND owner = 'theDeamonId').

Наконец, последнее ОБНОВЛЕНИЕ установит для строки значение «обработано» и может (или не может) удалить поле владельца.Хранение там также позволит получить некоторую статистику о работе демонов.

0 голосов
/ 11 февраля 2011

Насколько я знаю, вы не можете использовать MySQL для блокировки строки (используя встроенный метод). У вас есть два варианта:

  1. Если ваша таблица не будет прочитана каким-либо другим процессом, пока блокировки не будут сняты, вы можете использовать блокировку на уровне таблицы , как описано здесь

  2. Вы можете реализовать свою собственную базовую блокировку строк, обновив значение в каждой строке, которую вы обрабатываете, а затем попросите все остальные демоны проверить, установлено ли это свойство (достаточно тип данных BIT).

InnoDB блокирует на уровне строк для чтения и обновления в любом случае, но если вы хотите заблокировать строки на произвольный период, вам, возможно, придется воспользоваться вторым параметром.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...