Могут ли триггеры SQL CLR сделать это? Или есть лучший способ?

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

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

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

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

Любые другие идеи о том, как этого добиться?

8.01.2009 20:55:23
6 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

6
8.01.2009 21:01:17
Именно то, что я собирался предложить. Он будет безопасен с точки зрения транзакций и сохранит обработанные и необработанные записи в таблице, которая не повлияет на основные таблицы приложений. +1 за это решение!
evilhomer 8.01.2009 23:34:21
Используйте брокера служб SQL Server
Chris KL 10.02.2009 23:49:45
Хорошая идея, за исключением того, что вы потеряете все следы измененного материала (то есть содержимого таблицы DELETED, доступной только во время выполнения триггера). Зависит от того, что вам нужно, я полагаю.
David Catriel 15.12.2011 18:55:43

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

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

3
15.07.2010 23:58:48

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

1
8.01.2009 21:00:27

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

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

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

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

1
9.01.2009 00:08:49

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

-1
9.01.2009 13:52:09

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

2
10.02.2009 23:49:13
Согласовано. Код .net даже не должен быть процедурой, хранимой в clr - он может использовать содержимое очереди другого процесса.
Sean Reilly 2.03.2009 19:33:56