SQL Выберите строки из таблицы и обновите те же строки - PullRequest
5 голосов
/ 02 ноября 2011

Я хочу:

  1. Выберите N строк из таблицы для обработки, где flag = 0
  2. Выполнить некоторую работу над второй таблицей, используя значения из этих N строк
  3. Обновите эти N строк и установите флаг = 1

У меня есть параллельные процессы, выполняющие эту работу вместе, и я хочу, чтобы все работали над уникальными строками. Как я могу это гарантировать?

Ответы [ 2 ]

5 голосов
/ 02 ноября 2011

Я предполагаю, что вы работаете на SQL Server (из-за тега), если нет, то мой ответ не применим. Одной блокировки недостаточно. Если вы используете блокировку записей базы данных, сервер SqL заблокирует другие процессы, пытающиеся получить доступ к заблокированной строке, и фактически вы будете обрабатывать только одну строку за раз. Решение для вас - объединить блокировку строки с подсказкой READPAST, чтобы пропущенные кем-то строки были пропущены. Вот что должен делать каждый процесс:

  1. выберите следующую разблокированную строку для обработки и заблокируйте ее
  2. сделать работу
  3. обновить строку и завершить транзакцию

select top 1 id, ... from TheTable with (updlock, readpast) where flag = 0

//do the work now

update TheTable set flag = 1 where id=<previously retrieved id>

Приятно, что операция выбора следующей разблокированной строки и ее блокировки является атомарной, поэтому она гарантирует, что никто другой не сможет выбрать такую ​​же строку.

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

Один из способов состоит в том, чтобы мастер-программа раздала сегменты дочерним потокам.

Другой способ - заблокировать таблицу, получить CEIL(N/#processes) строк, где флаг = 0, обновить флаг до 2, затемснять замок.Затем следующий процесс будет продолжен, так как он получил блокировку, и поскольку flag = 2, он не получит эти строки.

У вас есть два способа заблокировать таблицу - вы можете либо заблокировать все, либо сделатьВЫБЕРИТЕ ... ДЛЯ ОБНОВЛЕНИЯ с ограничением (чтобы не получить слишком много строк).См .: ВЫБРАТЬ ДЛЯ ОБНОВЛЕНИЯ с SQL Server

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

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