Существует ли стандартный шаблон для сканирования таблицы заданий, выполняющей некоторые действия? - PullRequest
5 голосов
/ 13 марта 2010

(я понимаю, что мой заголовок плохой. Если после прочтения вопроса у вас возникли какие-то улучшения, пожалуйста, либо отредактируйте его, либо скажите мне, и я его изменю).

У меня есть относительно распространенный сценарий таблицы заданий, в которой есть 1 строка для некоторой вещи, которую нужно сделать. Например, это может быть список писем для отправки. Таблица выглядит примерно так:

ID    Completed    TimeCompleted   anything else...
----  ---------    -------------   ----------------
1     No                           blabla
2     No                           blabla
3     Yes          01:04:22
...

Я ищу либо стандартную практику / шаблон (или код - предпочтительно C # / SQL Server) для периодического «сканирования» (я использую термин «сканирование» очень слабо) этой таблицы, для поиска незавершенных элементов, выполнение действия, а затем отметка их завершена после успешного завершения.

В дополнение к базовому процессу выполнения вышесказанного я рассматриваю следующие требования:

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

Некоторые другие мысли:

  • Я не особенно обеспокоен реализацией, осуществляемой в базе данных (например, в коде T-SQL или PL / SQL), по сравнению с некоторым внешним программным кодом (например, автономным исполняемым файлом или некоторым действием, запускаемым веб-страницей), который выполняется против базы данных
  • Является ли часть «выполнение действия» синхронной или асинхронной, я не рассматриваю этот вопрос как часть этого вопроса.

Ответы [ 3 ]

1 голос
/ 13 марта 2010

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

1) Один процесс помещает «сообщение о работе» (возможно, просто идентификатор) в очередь.

2) Другой процесс следит за очередью. Он опрашивает очередь на работу и извлекает найденные задания из очереди, по очереди, в порядке их получения. Элементы, которые вы сняли с очереди, фактически помечаются как «в процессе» - они больше не доступны другим процессам.

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

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

.NET поддержка включает в себя Microsoft Message Queue и либо Windows Communication Foundation, либо классы в пространстве имен System.Messaging. Требуется некоторая настройка и настройка (необходимо создать очереди и настроить разрешения), но оно того стоит.

1 голос
/ 13 марта 2010

Если вы используете SQL 2005+, возможно, вы захотите изучить Service Broker . Это в значительной степени разработано для этого.

1 голос
/ 13 марта 2010

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

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