Триггер SQLCLR против службы Windows. Когда уместно использовать SQLCLR?

У нас есть приложение электронной коммерции .NET с серверной частью SQL Server 2005. Новый заказ требует определенной «постобработки». Эти задачи включают отправку электронных писем, создание файлов, загрузку файлов на FTP-сервер и выполнение операций CRUD со службой данных WCF. Код для выполнения всех этих задач уже существует в виде нескольких библиотек классов .NET.

В моей команде ведутся дебаты о том, где разместить этот код. Я написал простую службу Windows, которая через регулярные промежутки времени опрашивает базу данных и при обнаружении новых транзакций (на основе флагов) в базе данных выполняет необходимые действия и регистрирует любые ошибки. В качестве альтернативы был предложен триггер SQLCLR INSERT, запускающий обработку.

Я знаю, что технически возможно выполнить большую часть (все?) из вышеперечисленных задач в SQLCLR — я даже нашел несколько статей, объясняющих, как использовать веб-сервисы из SQLCLR, так что, по-видимому, люди так и делают. Но я все еще колеблюсь. Был ли SQLCLR когда-либо предназначен для такого рода вещей? А если нет, то какие могут быть практические недостатки? Что касается потенциальных преимуществ триггера SQLCLR по сравнению со службой Windows, я вижу только одно: меньше трафика базы данных. Сначала мы ожидаем очень небольшой объем транзакций, поэтому служба Windows будет генерировать некоторый «расточительный» трафик. Но сервис находится в том же ящике, что и база данных, так что он даже не влияет на сеть, только на внутренние ресурсы сервера.

Наконец, третья возможность — использовать триггер SQLCLR для сохранения простого маркера в файловой системе и использовать FileSystemWatcher в службе Windows (вместо Timer) для выполнения задач по мере необходимости.

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


person Antony    schedule 18.10.2010    source источник
comment
В журнале MSDN я нашел следующую статью: bit.ly/cyxEbw. Он очень хорошо решает компромиссы между T-SQL и SQL CLR, но, к сожалению, не отвечает на мой вопрос.   -  person Antony    schedule 19.10.2010


Ответы (2)


При рассмотрении аналогичного процесса здесь были некоторые вещи, которые мы учитывали.

  1. Что происходит, когда зависимая система (почта, ftp) недоступна?
  2. Как происходит восстановление после сбоя?
  3. Если мы находимся в состоянии сбоя, что происходит с новыми записями. Пытаются ли они выполнить постобработку, даже если мы знаем, что система не работает?
  4. Каков набор навыков тех, кто поддерживает производственную систему?
  5. Как контролируется этот процесс?
  6. Использует ли система постобработки ресурсы основной системы при обработке? Как бы вы их разделили?
  7. Поддерживается ли отказоустойчивость?

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

person Conrad Frix    schedule 18.10.2010
comment
+1, потому что одного пункта 1 достаточно, чтобы потопить любое решение на основе триггера. остальное только для дополнительной оценки ;) - person Remus Rusanu; 19.10.2010
comment
Это это действительно хороший момент. Это дыра, даже если мы продолжим использовать флаги базы данных и проверять все записи при каждой вставке, потому что в чистом сценарии триггера CLR повторная попытка постобработки не предпринимается до тех пор, пока не поступит следующая транзакция, что может занять несколько дней. - person Antony; 20.10.2010

Есть некоторые вещи, для которых была разработана SQL CLR - и это не одна из них, добавление такого рода вещей в триггер INSERT действительно заставило бы младенца Иисуса плакать.

Одним из возможных решений может быть использование уведомления о запросе, чтобы уменьшить нагрузку между службой и базой данных — можно выбрать другой маршрут, разрешив «пингование» службы через UDP или что-то подобное легковесное — это означает, что вы t вызывает массовое выполнение INSERTS (и, следовательно, вы не блокируете базовую таблицу на чрезмерное количество времени).

person Matt Whitfield    schedule 18.10.2010
comment
Пока что вы подтверждаете мое подозрение, что SQL CLR не предназначена для такой обработки, которую мы делаем. Не могли бы вы немного рассказать о специфике того, что в этом такого злого? Может ли это вывести из строя SQL Server? Как? - person Antony; 19.10.2010
comment
Это не приведет к остановке SQL Server (если только вы не создадите сборку UNSAFE, чтобы делать то, что хотите, а затем каким-то образом испортите пространство процесса), но вы можете легко заставить блокировки удерживаться намного дольше, чем нужно, создав триггер, который работает в течение длительного времени. Если вы делаете что-то в сборке UNSAFE, то все ставки сняты — ограничения модели программирования в CLR в SQL Server существуют по какой-то причине — я не настолько глуп, чтобы притворяться, что знаю все входы и выходы, но они вообще надо уважать... - person Matt Whitfield; 19.10.2010
comment
+1 за то, что заставил младенца Иисуса плакать, и за рекомендацию уведомления о запросах в качестве механизма изменения БД. - person Conrad Frix; 19.10.2010
comment
@Antony: поскольку SQLCLR размещается в инфраструктуре SOS SQL Server, которая предоставляет такие службы CLR, как потоки, выделение памяти и примитивы синхронизации, все, что пойдет не так в SQLCLR, повлияет на внутренние компоненты SQL. В частности, фоновые потоки, которые «захвачены» SQLCR и заблокированы в ожидании некоторых из них, будут потреблять один из ценных рабочих потоков в ОС SQL. Код SQLCR, который выполняет внешний доступ (WCF, почта, WebRequests, ftp и т. д.), особенно подвержен этой проблеме. Эта проблема действительно происходит, я видел это несколько раз. SQL в конце концов зависает - person Remus Rusanu; 19.10.2010
comment
@Matt Является ли проблема блокировки чем-то особенным для триггеров CLR или для всех триггеров? - person Antony; 20.10.2010