SQL Server 2008 - выбор несвязанных строк - PullRequest
1 голос
/ 03 июня 2011

У меня есть два параллельных процесса, и у меня есть два запроса, например ::

select top 10 * into #tmp_member
from member
where status = 0
order by member_id

, а затем

update member
set process_status = 1
from member inner join #tmp_member m
on member.member_id=m.member_id

Я бы хотел, чтобы каждый процесс выбирал разные строки, поэтому, если строка уже была выбрана первым процессом, не используйте ее в списке результатов второго процесса.

Должен ли я играть с замками? UPDLOCK, ROWLOCK, READPAST намеки может быть? Или есть более простое решение?

Любая помощь приветствуется,

ура

б

Ответы [ 3 ]

3 голосов
/ 03 июня 2011

Вам нужны подсказки.

См. Мой ответ здесь: Состояние гонки очереди процесса SQL Server

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

update m
set process_status = 1
OUTPUT Inserted.member_id
from
  (
  SELECT top 10
      process_status, member_id
    from member WITH (ROWLOCK, READPAST, UPDLOCK)
    where status = 0
    order by member_id
  ) m

Сводка: если вы хотите, чтобы несколько процессов

  1. select 10 rows where status = 0
  2. set process_status = 1
  3. верните набор результатов безопасным, параллельным образом

... затем используйте этот код.

0 голосов
/ 03 июня 2011

Для достижения цели работы нескольких процессов за столом участника вам не нужно «поиграться с блокировками».Вам нужно будет перейти с таблицы #tmp_member на глобальную временную таблицу или постоянную таблицу.Таблице также понадобится столбец для отслеживания того, какой процесс управляет строкой члена /

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

0 голосов
/ 03 июня 2011

Ну, проблема в том, что ваш выбор / обновление не является атомарным - второй процесс может выбрать первые 10 элементов между первым выбранным процессом и перед обновлением.

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

DECLARE @MyTableVar table(member_ID INT)
UPDATE TOP (10) Members
SET 
 member_id = member_id,
 process_status = 1
WHERE status = 0
OUTPUT inserted.member_ID
INTO @MyTableVar;

После этого @MyTableVar должен содержать все обновленные идентификаторы членов.

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