Изменить набор результатов SQL перед возвратом из хранимой процедуры - PullRequest
3 голосов
/ 25 февраля 2010

У меня есть простая таблица в моей базе данных SQL Server 2008:

Tasks_Table
-id
-task_complete
-task_active
-column_1
-..
-column_N

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

Я хочу иметь возможность масштабировать свою систему в будущем. До сих пор только 1 сервис на 1 компьютере читал из таблицы. У меня есть хранимая процедура, которая выбирает все незавершенные и неактивные задачи. Когда служба начинает обрабатывать задачи, она обновляет флаг task_active во всех возвращаемых строках.

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

Я решил, что мне нужно заблокировать таблицу (только 1 читатель за раз - я знаю, что должен использовать соответствующий УРОВЕНЬ ИЗОЛЯЦИИ) и обновлять флаг task_active в каждой строке набора результатов перед возвратом набора результатов.

Итак, мой вопрос, как изменить набор результатов SELECT в хранимой процедуре перед его возвратом?

1 Ответ

2 голосов
/ 25 февраля 2010

Это типичный шаблон очереди, реализованный с использованием предложения OUTPUT и описанный в MSDN, см. Пункт «Очереди» в Предложение OUTPUT (Transact-SQL) :

UPDATE TOP(1) Tasks_Table WITH (ROWLOCK, READPAST)
 SET task_active = 1
 OUTPUT INSERTED.id,INSERTED.column_1, ...,INSERTED.column_N 
 WHERE task_active = 0;

Подсказка ROWLOCK, READPAST обеспечивает высокую пропускную способность и высокую степень параллелизма: несколько потоков / обработанные могут ставить новые задачи в очередь, в то время как потоки / задачи очереди процессов смешиваются. Нет гарантии заказа.

Обновлено

Если вы хотите заказать результат, вы можете использовать CTE:

WITH cte AS (
  SELECT TOP(1) id, task_active, column_1, ..., column_N
  FROM Task_Table WITH (ROWLOCK, READPAST)
  WHERE task_active = 0
  ORDER BY <order by criteria>)
UPDATE cte
  SET task_active = 1
OUTPUT INSERTED.id, INSERTED.column_1, ..., INSERTED.column_N;

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

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