Каковы некоторые методы написания масштабируемых служб при использовании таблицы SQL Server 2000 в качестве очереди работы? - PullRequest
1 голос
/ 01 февраля 2011

Если у меня есть таблица базы данных SQL Server 2000, которую я использую как очередь выполняемой работы, каковы наилучшие методы для выполнения этой работы в масштабируемом режиме? Сценарий: существует служба Windows, которая будет выполнять некоторую, потенциально долгую работу, для каждой строки в таблице. Когда запущен только один сервис, легко собрать первые 10 или 100 строк, выполнить работу (даже в многопоточном режиме), а затем обновить эти 10 или 100 строк, чтобы сказать, что работа выполнена. Если я хочу запустить эту же службу на 2 серверах, мне нужен механизм блокировки, чтобы службы не захватывали одни и те же строки. Сначала я хотел бы добавить в таблицу поле, которое указывает, что строка заблокирована во время выполнения работы, поэтому служба будет обновлять это «заблокированное» поле до тех пор, пока работа не будет завершена, и при выборе группы строк для работы будет убедитесь, что строки не заблокированы.

Это лучший способ справиться с этим типом работы или можно использовать блокировку строк на уровне базы данных, чтобы сделать то же самое? Я знаю, что более идеальным решением, вероятно, была бы очередь сообщений, но давайте предположим, что я хочу использовать таблицу базы данных для очереди работы. Также было высказано предположение, что этот тип вещей гораздо проще в мире Oracle, где решением будет блокировка строк на уровне базы данных, мне не повезло с использованием блокировки строк в SQL Server 2000, но, возможно, что-то упущено.

Обновление: добавлены теги

1 Ответ

2 голосов
/ 01 февраля 2011

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

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

SELECT TOP 1 JobId, JobData FROM Queue WHERE Worker IS NULL ORDER BY QueueTime

Затем работник может попытаться претендовать на владение работой, выполнив инструкцию обновления:

UPDATE Queue SET Worker = 'workerid' WHERE JobId = 'jobid' AND Worker IS NULL

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

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

...