Как атомарно выбрать строки в Mysql? - PullRequest
0 голосов
/ 04 ноября 2011

У меня 5+ одновременно обрабатывает выбор строк из одной и той же таблицы MySQL. Каждый процесс выбирает 100 строк, обрабатывает их и удаляет выбранные строки.

Но я получаю одну и ту же строку, выбранную и обработанную 2 и более раз.

Как мне избежать этого на стороне MYSQL или Ruby on Rails?

Приложение построено на Ruby On Rails ...

Ответы [ 3 ]

4 голосов
/ 04 ноября 2011

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

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

И да, вернитесь к своим старым вопросам и утвердите некоторые ответы.Я видел по крайней мере одну, которую ты определенно пропустил.

3 голосов
/ 05 ноября 2011

Ответ Эрика хорош, но я думаю, что мне следует немного прояснить ...

У вас есть несколько дополнительных столбцов в вашей таблице:

lockhost VARCHAR(60),
lockpid INT,
locktime INT, -- Or your favourite timestamp.

По умолчанию все они равны NULL.

Тогда у вас есть рабочие процессы, которые "запрашивают" строки, выполняя:

UPDATE tbl SET lockhost='myhostname', lockpid=12345,
 locktime=UNIX_TIMESTAMP() WHERE lockhost IS NULL ORDER BY id
 LIMIT 100

Затем вы обрабатываете заявленные строки с помощью SELECT ... WHERE lockhost = 'myhostname' и lockpid = 12345

После того, как вы закончите обработку строки, вы сделаете все необходимые обновления и установите для lockhost, lockpid и locktime значение NULL (или удалите его).

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

Если во время обработки пакета происходит сбой процесса, вы можете проверить, является ли столбец «время блокировки» очень старым (намного старше, чем обработка может занять, скажем, несколько часов). Затем вы можете просто вернуть некоторые строки, которые имеют старое «время блокировки», даже если их lockhost не равен нулю.

Это довольно распространенный «шаблон очереди» в базах данных; это не очень эффективно. Если у вас очень высокий уровень поступления элементов в очередь или выхода из нее, рассмотрите возможность использования подходящего сервера очереди.

0 голосов
/ 04 ноября 2011
...