Ответ 1
Прежде всего, вырезать из уравнения очевидное несоответствие: уведомление о запросах не подходит для этого, потому что оно предназначено для устранения недействительности кэша относительно стабильных данных. С QN вы узнаете только, что таблица изменилась, но вы не сможете узнать, что изменилось.
Престижность вам в том, что выяснить, почему триггеры, вызывающие SQLCRL, не будут работать: последовательность отменяется при откате.
Так что же работает? Рассмотрим это: BizTalk Server. Другими словами, вокруг этого проблемного пространства существует целый бизнес, и решения далеки от тривиальных (иначе никто не купил бы такие продукты).
Вы можете получить довольно далеко, следуя нескольким принципам:
- расцепления. Триггеры, основанные на событиях, в порядке, но не отправляйте сообщение с триггера. Помимо проблемы согласованности при откате, у вас также есть проблема с задержкой в том, что каждая операция DML теперь ожидает внешнего вызова API (RabbitMQ send) и проблемы доступности внешней ошибки вызова API (если RabbitMQ недоступен, ваша БД недоступна). Решение состоит в том, чтобы триггер использовал обычные таблицы в качестве очередей, триггер будет выставлять сообщение в локальной очереди db (т.е. Будет вставляться в эту таблицу) и процесс будет обслуживать эту очередь, выгружая сообщения (т.е. удаляя из таблицы) и перенаправляя их в RabbitMQ. Это отделяет транзакцию от операции RabbitMQ (внешний процесс может видеть сообщение только в том случае, если первоначальный xact совершает), но стоимость - это очевидная добавленная латентность (есть дополнительный переход, локальная таблица выступает в качестве очереди).
- идемпотентность. Так как RabbitMQ не может регистрироваться в распределенных транзакциях с базой данных, вы не можете гарантировать атомарность операции БД (dequeue из локальной таблицы, действующей как очередь) и операцию RabbitMQ (отправка). Либо один может преуспеть, если другой не удался, и просто нет возможности обойтись без явной поддержки регистрации заявок на участие в транзакциях. Это означает, что приложение будет отправлять повторяющиеся сообщения каждый раз в то время (обычно, когда по какой-то причине ситуация уже идет плохо). И быстрый хэдз-ап: включение в действие явных сообщений "подтверждения" и отправка порядковых номеров - это битва, так как вы быстро обнаружите, что вы изобретаете TCP поверх сообщений, эта дорога вымощена телами.
- Допуск. По тем же причинам, что и выше, каждый из них теперь передается, и сообщение, которое, как вы считаете, было отправлено, никогда не будет выполнено. Опять же, какой ущерб это причиняет, полностью зависит от бизнеса. Проблема заключается не в том, как предотвратить эту ситуацию (это почти невозможно...), но как обнаружить эту ситуацию и что с ней делать. Никакой серебряной пули, я боюсь.
Вы упомянули об этом Service Broker (тот факт, что Powering Query Notification является наименее интересным аспектом этого...). Будучи платформой для обмена сообщениями, встроенной в SQL Server, которая предлагает гарантию доставки точно в порядке и полностью транслируется, она решит все вышеупомянутые болевые точки (вы можете SEND
от триггеров с безнаказанностью вы можете использовать Активацию для решения проблемы с задержкой, вы никогда не увидите дубликат или недостающее сообщение, есть четкая семантика ошибок) и некоторые другие болевые точки Раньше я не упоминал (согласованность резервного копирования/восстановления, так как данные и сообщения находятся на одной единице хранения - база данных, cosnsitnecy переадресации HA/DR, поскольку SSB поддерживает зеркалирование и кластеризацию базы данных и т.д.). Однако обратная связь заключается в том, что SSB способен разговаривать только с другой службой SSB, другими словами, ее можно использовать только для обмена сообщениями между двумя (или более) экземплярами SQL Server. Любое другое использование требует от сторон использования SQL Server для обмена сообщениями. Но если ваши конечные точки - это все SQL Server, то подумайте, что есть несколько широкомасштабных развертываний с использованием Service Broker. Обратите внимание, что конечные точки, такие как php или asp.net, могут считаться конечными точками SQL Server, они просто программируют уровни поверх API БД, другая конечная точка, скажем, должна посылать сообщения с карманных устройств (телефонов) непосредственно в базу данных (и только те 99% времени проходят через веб-службу, что означает, что они могут в конечном итоге достичь SQL Server). Другое соображение заключается в том, что SSB ориентирован на пропускную способностьи надежная доставка, а не низкая латентность. Определенно, это не технология, которую можно использовать для возврата ответа в веб-запросе HTTP, например. Является технологией, которую нужно использовать для отправки для обработки чего-либо, вызванного веб-запросом.