Может ли триггер SQL вызвать веб-службу?

Я создаю RESTful API для iPhone-приложения.

Когда пользователь "проверяет" [Вставляет новую строку в таблицу], я хочу затем взять данные из этой вставки и вызвать веб-службу, которая будет отправлять push-уведомления на основе этой вставки.

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

Интересно, были ли у вас какие-то мысли по этому поводу или если был лучший подход, о котором я не думал.

Ответ 1

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

Моя рекомендация заключалась бы в том, чтобы отделить задачу "замечать", что вам нужно вызвать веб-сервис в вашем триггере от фактического выполнения этого вызова веб-службы.

Что-то вроде:

  • в вашем триггерном коде, добавьте "do call the webservice later" в таблицу (просто INSERT, чтобы сохранить ее и быстро), что все)

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

Триггер - очень сложная вещь - она ​​всегда должна быть очень быстрой, очень скудной - делать INSERT или два максимум - и во что бы то ни стало избегать курсоров в триггерах или других длительных операциях (например, вызов веб-службы )

У Brent Ozar есть отличная трансляция (представленная на SQL PASS) на Топ-10 ошибок разработчиков, которые не масштабируются и триггеры, являются первыми на что он сосредоточился! Очень рекомендуется

Ответ 2

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

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

В худшем случае вы всегда можете создать свою собственную страницу "API"; вместо того, чтобы напрямую вставлять данные, запросите страницу API, которая может вставлять данные и делать push-уведомления.

Ответ 3

Это зависит от потребностей бизнеса. Обычно я избегаю использовать триггеры для этого, так как это бизнес-логика и должен обрабатываться BL.

Но ответ на вопрос "Да" - вы можете это сделать, просто не забудьте вызвать веб-службу асинхронно, чтобы он не задерживал вставку, пока заканчивается вызов веб-службы.

Вы также можете рассмотреть возможность использования веб-службы OneWay, то есть пожара и забыть.

Но, как указывали другие, вам всегда лучше не использовать триггер.

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

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

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

Ответ 4

Хорошей практикой является то, что эта веб-страница сделает запись в другую таблицу (я вызову message_queue), когда пользователь попадет на страницу.

Затем на сервере сканируется окно службы /* nix-демона на странице message_queue и выполняйте push-запросы через веб-службу в мобильное приложение. Вы можете использовать возможности обработки транзакций в SQL для управления обработкой очереди.

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

Ответ 5

Trigger- > Queue- > SP- > XP_XMDShell- > BAT- > cURL- > сторонний веб-сервис

Я использовал триггер для вставки записи в таблицу Queue, затем Сохраненная процедура с использованием курсора для выключения записей в очереди.

У меня не было WSDL или доступ к сторонним разработчикам API и срочная необходимость завершить прототип, поэтому Хранимая процедура вызывает XP_CMDShell, вызывая файл .bat с параметрами.

Файл bat управляет вызовом cURL, который управляет вызовом и ответом REST/JSON.

Это было бесплатно, быстро и надежно работает. Не архитектурно чист, но получил прототип с земли.