BEGIN DIALOG CONVERSATION (Transact-SQL)

Область применения: SQL Server Управляемый экземпляр SQL Azure

Создает диалог между двумя службами. Диалог — это сеанс связи, который обеспечивает доставку сообщений строго по порядку между двумя службами.

Соглашения о синтаксисе Transact-SQL

Синтаксис

BEGIN DIALOG [ CONVERSATION ] @dialog_handle  
   FROM SERVICE initiator_service_name  
   TO SERVICE 'target_service_name'  
       [ , { 'service_broker_guid' | 'CURRENT DATABASE' }]   
   [ ON CONTRACT contract_name ]  
   [ WITH  
   [  { RELATED_CONVERSATION = related_conversation_handle   
      | RELATED_CONVERSATION_GROUP = related_conversation_group_id } ]   
   [ [ , ] LIFETIME = dialog_lifetime ]   
   [ [ , ] ENCRYPTION = { ON | OFF }  ] ]  
[ ; ]  

Аргументы

@ dialog_handle
— переменная, используемая для хранения системно сгенерированного дескриптора диалога для нового диалога, возвращаемого BEGIN DIALOG CONVERSATION оператором. Переменная должна иметь тип uniqueidentifier.

От SERVICEinitiator_service_name
Указывает службу стороны, вызывающей диалог. Указанное имя должно быть именем службы в текущей базе данных. Очередь, указанная для вызывающей службы, получает сообщения, возвращенные целевой службой, и сообщения, созданные компонентом Service Broker для данного диалога.

К SERVICE«target_service_name»
Указывает целевую службу, с которой необходимо начать диалог. target_service_name имеет тип nvarchar(256). Компонент Service Broker производит побайтовое сравнение при поиске соответствия строке target_service_name. Другими словами, сравнение чувствительно к регистру и не использует текущие параметры сортировки.

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

service_broker_guid имеет тип nvarchar(128). Чтобы найти service_broker_guid для базы данных, выполните следующий запрос в базе данных:

SELECT service_broker_guid  
FROM sys.databases  
WHERE database_id = DB_ID() ;  

Примечание.

Этот параметр недоступен в автономной базе данных.

«ТЕКУЩИЙ DATABASE»
Указывает на то, что диалог использует аргумент service_broker_guid для текущей базы данных.

НА CONTRACT
Указывает контракт, которого придерживается данный диалог. Контракт должен существовать в текущей базе данных. Если целевая служба не принимает новые диалоги указанного контракта, компонент Service Broker возвращает сообщение об ошибке диалога. Когда этот пункт опускается, разговор следует контракту под названием DEFAULT.

RELATED_CONVERSATION =related_conversation_handle
Указывает существующую группу сообщений, к которой добавляется новый диалог. Если присутствует данное предложение, новый диалог принадлежит к той же группе сообщений, что и диалог, указанный аргументом related_conversation_handle. Аргумент related_conversation_handle должен иметь тип, способный неявно преобразовываться в тип uniqueidentifier. Инструкция завершается неудачно, если аргумент related_conversation_handle не ссылается на существующий диалог.

RELATED_CONVERSATION_GROUP =related_conversation_group_id
Указывает существующую группу сообщений, к которой добавляется новый диалог. Если присутствует данное предложение, новый диалог будет добавлен к группе сообщений, указанной аргументом related_conversation_group_id. Аргумент related_conversation_group_id должен иметь тип, способный неявно преобразовываться в тип uniqueidentifier. Если аргумент related_conversation_group_id не ссылается на существующую группу сообщений, компонент Service Broker создает новую группу сообщений с заданным аргументом related_conversation_group_id и связывает новый диалог с полученной группой сообщений.

LIFETIME =dialog_lifetime
Указывает максимальный период времени, в течение которого диалог будет оставаться открытым. Для успешного завершения диалога обе конечные точки должны явно завершить диалог до истечения его времени жизни. Значение аргумента dialog_lifetime должно быть выражено в секундах. Время существования типа int. Если предложение LIFETIME не указано, время существования диалогового окна является максимальным значением типа данных int .

ШИФРОВАНИЕ
Указывает, должны ли отправленные и полученные в данном диалоге сообщения шифроваться, если они отправляются за пределы экземпляра Microsoft SQL Server. Диалог, который подлежит шифрованию, является защищенным диалогом. Если используется предложение ENCRYPTION = ON, а сертификаты, необходимые для поддержки шифрования, не настроены, компонент Service Broker возвращает сообщение об ошибке диалога. При использовании предложения ENCRYPTION = OFF сообщения шифруются в том случае, если привязка удаленной службы настроена на использование аргумента target_service_name; иначе сообщения отсылаются нешифрованными. Если данное предложение отсутствует, присваивается значение по умолчанию ON.

Примечание.

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

Замечания

Все сообщения являются частью диалога. Следовательно, перед отправкой сообщения целевой службе служба вызывающей стороны должна начать с ней диалог. Информация, указанная в BEGIN DIALOG CONVERSATION выписке, схожа с адресом в письме; Service Broker использует эту информацию для доставки сообщений соответствующему сервису. Сервис, указанный в оговорке TO SERVICE , — это адрес, на который отправляются сообщения. Сервис, указанный в клаузе FROM SERVICE , — это обратный адрес, используемый для ответных сообщений.

Объект разговора не обязан звонить BEGIN DIALOG CONVERSATION. Компонент Service Broker создает диалог в целевой базе данных, когда от инициатора диалога поступает первое сообщение.

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

Если в BEGIN DIALOG CONVERSATION заявлении не указана связанная беседа или группа, Service Broker создаёт новую группу для нового разговора.

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

Команда BEGIN DIALOG CONVERSATION блокирует группу разговоров, содержащую возвращённый dialog_handle . Если команда содержит предложение RELATED_CONVERSATION_GROUP, группой сообщений для dialog_handle является та, которая указана в аргументе related_conversation_group_id. Если команда содержит предложение RELATED_CONVERSATION, группой сообщений для dialog_handle является та, которая указана в аргументе related_conversation_handle.

BEGIN DIALOG CONVERSATION не является валидным в пользовательской функции.

Разрешения

Для начала диалога текущий пользователь должен иметь RECEIVE разрешение на очередь сервиса, указанного в пункте FROM команды, и разрешение REFERENCES для указанного контракта.

Примеры

А. Создание диалога

В следующем примере начинается диалог, идентификатор которого сохраняется в параметре @dialog_handle.. Служба //Adventure-Works.com/ExpenseClient является инициатором диалога, а служба //Adventure-Works.com/Expenses — его целевой службой. Этот диалог следует контракту //Adventure-Works.com/Expenses/ExpenseSubmission.

DECLARE @dialog_handle UNIQUEIDENTIFIER ;  
  
BEGIN DIALOG CONVERSATION @dialog_handle  
   FROM SERVICE [//Adventure-Works.com/ExpenseClient]  
   TO SERVICE '//Adventure-Works.com/Expenses'  
   ON CONTRACT [//Adventure-Works.com/Expenses/ExpenseSubmission] ;  

B. Создание диалога с явно заданным временем жизни

В следующем примере создается двусторонний диалог с сохранением идентификатора диалога в параметре @dialog_handle. Служба //Adventure-Works.com/ExpenseClient является инициатором диалога, а служба //Adventure-Works.com/Expenses — его целевой службой. Этот диалог следует контракту //Adventure-Works.com/Expenses/ExpenseSubmission. Если диалог не был закрыт командой END CONVERSATION в течение 60 нескольких секунд, брокер завершает диалог ошибкой.

DECLARE @dialog_handle UNIQUEIDENTIFIER ;  
  
BEGIN DIALOG CONVERSATION @dialog_handle  
   FROM SERVICE [//Adventure-Works.com/ExpenseClient]  
   TO SERVICE '//Adventure-Works.com/Expenses'  
   ON CONTRACT [//Adventure-Works.com/Expenses/ExpenseSubmission]  
   WITH LIFETIME = 60 ;  

В. Создание диалога с определенным экземпляром брокера

В следующем примере создается двусторонний диалог с сохранением идентификатора диалога в параметре @dialog_handle. Служба //Adventure-Works.com/ExpenseClient является инициатором диалога, а служба //Adventure-Works.com/Expenses — его целевой службой. Этот диалог следует контракту //Adventure-Works.com/Expenses/ExpenseSubmission. Компонент Service Broker перенаправляет сообщения этого диалога компоненту Service Broker с идентификатором GUID a326e034-d4cf-4e8b-8d98-4d7e1926c904.

DECLARE @dialog_handle UNIQUEIDENTIFIER ;  
  
BEGIN DIALOG CONVERSATION @dialog_handle  
   FROM SERVICE [//Adventure-Works.com/ExpenseClient]  
   TO SERVICE '//Adventure-Works.com/Expenses',   
              'a326e034-d4cf-4e8b-8d98-4d7e1926c904'  
   ON CONTRACT [//Adventure-Works.com/Expenses/ExpenseSubmission] ;  

D. Создание диалога и его соотнесение с существующей группой сообщений

В следующем примере создается двусторонний диалог с сохранением идентификатора диалога в параметре @dialog_handle. Служба //Adventure-Works.com/ExpenseClient является инициатором диалога, а служба //Adventure-Works.com/Expenses — его целевой службой. Этот диалог следует контракту //Adventure-Works.com/Expenses/ExpenseSubmission. Компонент Service Broker связывает этот диалог с группой сообщений, указанной параметром @conversation_group_id, а не создает новую группу сообщений.

DECLARE @dialog_handle UNIQUEIDENTIFIER;
DECLARE @conversation_group_id UNIQUEIDENTIFIER;

SET @conversation_group_id = <retrieve conversation group ID from database>;

BEGIN DIALOG CONVERSATION @dialog_handle
    FROM SERVICE [//Adventure-Works.com/ExpenseClient]
    TO SERVICE '//Adventure-Works.com/Expenses'
    ON CONTRACT [//Adventure-Works.com/Expenses/ExpenseSubmission]
    WITH RELATED_CONVERSATION_GROUP = @conversation_group_id;

Е. Создание диалога с явно заданным временем жизни и соотнесение диалога с одним из существующих диалогов

В следующем примере создается двусторонний диалог с сохранением идентификатора диалога в параметре @dialog_handle. Служба //Adventure-Works.com/ExpenseClient является инициатором диалога, а служба //Adventure-Works.com/Expenses — его целевой службой. Этот диалог следует контракту //Adventure-Works.com/Expenses/ExpenseSubmission. Новый диалог принадлежит к той же группе сообщений, что и @existing_conversation_handle. Если диалог не был закрыт командой END CONVERSATION в течение 600 нескольких секунд, Service Broker завершает диалог ошибкой.

DECLARE @dialog_handle UNIQUEIDENTIFIER;
DECLARE @existing_conversation_handle UNIQUEIDENTIFIER;

SET @existing_conversation_handle = <retrieve conversation handle from database>;

BEGIN DIALOG CONVERSATION @dialog_handle
   FROM SERVICE [//Adventure-Works.com/ExpenseClient]
   TO SERVICE '//Adventure-Works.com/Expenses'
   ON CONTRACT [//Adventure-Works.com/Expenses/ExpenseSubmission]
   WITH RELATED_CONVERSATION = @existing_conversation_handle
   LIFETIME = 600;

F. Создание диалога с дополнительным шифрованием

В следующем примере создается двусторонний диалог с сохранением идентификатора диалога в параметре @dialog_handle. Служба //Adventure-Works.com/ExpenseClient является инициатором диалога, а служба //Adventure-Works.com/Expenses — его целевой службой. Этот диалог следует контракту //Adventure-Works.com/Expenses/ExpenseSubmission. Диалог в этом примере разрешает сообщению перемещаться в сети без шифрования в случае, если шифрование недоступно.

DECLARE @dialog_handle UNIQUEIDENTIFIER  
  
BEGIN DIALOG CONVERSATION @dialog_handle  
   FROM SERVICE [//Adventure-Works.com/ExpenseClient]  
   TO SERVICE '//Adventure-Works.com/Expenses'  
   ON CONTRACT [//Adventure-Works.com/Expenses/ExpenseSubmission]  
   WITH ENCRYPTION = OFF ;