Могут ли триггеры SQL CLR сделать это? Или есть лучший способ? - PullRequest
7 голосов
/ 08 января 2009

Я хочу написать сервис (возможно, на c #), который отслеживает таблицу базы данных. Когда запись вставляется в таблицу, я хочу, чтобы служба захватила вновь вставленные данные и выполнила с ними некоторую сложную бизнес-логику (слишком сложную для TSQL).

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

Проведя небольшое исследование, кажется, что, возможно, написание триггера CLR может помочь. Я мог бы написать триггер в C #, который срабатывает при вставке, а затем отправить вновь вставленные данные в службу Windows или WCF.

Как вы думаете, является ли это хорошим (или даже возможным) использованием триггеров SQL CLR?

Есть еще идеи, как этого добиться?

Ответы [ 6 ]

6 голосов
/ 09 января 2009

Возможно, вам следует отсоединить постобработку от вставки:

В триггере вставки добавьте PK записи в таблицу очередей.

В отдельном сервисе прочитайте из таблицы очередей и выполните сложную операцию. По завершении пометьте запись как обработанную (вместе с информацией об ошибке / состоянии) или удалите запись из очереди.

3 голосов
/ 09 января 2009

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

Я бы посоветовал сделать что-либо подобное с помощью Trigger как ненадлежащее использование функции базы данных, с которой в любом случае легко попасть в неприятности. Триггеры лучше всего использовать для структурной функциональности dbms с низкими издержками (например, детальной проверки ссылочной целостности) и должны быть легкими и синхронными. Это может быть сделано, но, вероятно, не будет хорошей идеей.

2 голосов
/ 11 февраля 2009

Я бы предложил иметь в таблице триггер, который вызывает SQL Server Service Broker , который затем (асинхронно) выполняет хранимую процедуру CLR, которая выполняет всю вашу работу в другом потоке.

1 голос
/ 09 января 2009

Я бы не рекомендовал использовать триггер CLR или любой другой тип триггера для этого. Вы открываете себя серьезной ремонтопригодности и потенциальным проблемам с блокировкой. (Очень простой триггер, который забирает вещи в таблицу аудита / очереди, может быть приемлем, если вы не заботитесь о @@ identity после вставок и никогда не заблокируете таблицу аудита / очереди)

Вместо этого из вашего приложения / orm вы должны инициировать вставку содержимого в таблицу очередей и регулярно обрабатывать эту очередь. Это можно сделать, запустив транзакцию в вашем ORM или запустив сохраненный процесс, когда транзакция запускает изменение и аудит / очередь атомарно. (будьте осторожны с блокировкой здесь)

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

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

1 голос
/ 09 января 2009

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

0 голосов
/ 09 января 2009

Почему бы не внедрить вставку в хранимую процедуру, а выполнить бизнес-логику в процедуре после вставки? Что в этом такого сложного, что его нельзя написать на T-SQL?

...