Разделение рабочей очереди между несколькими процессами

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

Допустим, у меня есть 1000 объектов, и каждый объект должен «обрабатываться» с разными интервалами (например, 15, 30 или 45 минут). Я хочу разделить работу между несколькими процессами, не опрашивая SQL Server каждую минуту в поисках дополнительной работы. Я прочитал много статей, связанных с уведомлением SqlDependency/Query, но не могу понять, как поставить работу в очередь и как ограничить каждый процесс набором рабочих элементов.

Я написал запрос SqlDependency, который выглядит следующим образом:

select f1, f2, etc from dbo.entity where LastRunDt < datediff(minute, 15, @dt)

Запрос выполняется с 0 результатами, но по прошествии 15 минут, что может привести к изменению этого набора записей (больше элементов в нем), уведомление не запускается. Я предполагаю, что это не сработает таким образом, поэтому я застрял в том, как поставить рабочие элементы в очередь.

Кроме того... когда я присоединяю 2 процесса к одной и той же рабочей очереди, каждый процесс получает уведомление (когда я запускаю запрос select * from dbo.entity SqlDependency и изменяю запись), но они оба получают одни и те же рабочие элементы. Мне нужно разделить рабочие элементы между доступными процессами, не зная, сколько есть слушателей, может быть 2 или 12 в зависимости от того, какие серверы подключены к сети, а какие отключены для обслуживания.

Клиенты будут написаны на C#.

Буду очень признателен за любые известные шаблоны, мысли или направления.


person Chris Gessler    schedule 17.07.2012    source источник


Ответы (2)


Вам не нужно задействовать Query Notification здесь. Используйте Service Broker напрямую.

Пусть ваше приложение C# выдает операторы WAITFOR(RECEIVE ...) для получения рабочих задач. Когда работа будет доступна, поставьте сообщение в очередь, используя SEND. Чтобы запланировать работу в будущем, используйте BEGIN CONVERSATION TIMER.

Кроме того, Service Broker может помочь вам фактически активировать код C# либо в качестве внутренней управляемой хранимой процедуры (см. Активация Service Broker) или как внешнее автономное приложение (см. Внешний активатор Service Broker).

person Remus Rusanu    schedule 17.07.2012
comment
ТАЙМЕР НАЧАЛА РАЗГОВОРА, вероятно, то, что я ищу. Я хотел создать цикл WHILE() с WAITFOR() внутри него, но знал, что есть способ получше. Спасибо. - person Chris Gessler; 17.07.2012
comment
Я решил использовать ТАЙМЕР НАЧАЛА РАЗГОВОРА, но у меня есть другая ситуация, на которую я ищу ответы. Мне нужны ваши комментарии — см. этот вопрос< /а> - person Chris Gessler; 23.07.2012

Похоже, вам нужна какая-то очередь сообщений. Есть несколько распространенных пакетов промежуточного программного обеспечения, таких как NServiceBus.

Вы также можете использовать ServiceBroker, который прекрасно интегрируется с SQL Server транзакционным и быстрым способом.

person usr    schedule 17.07.2012
comment
Спасибо... У меня много применений для NServiceBus, но не в этом случае. Я думаю, что Service Broker — это то, что нужно. - person Chris Gessler; 17.07.2012