END CONVERSATION (Transact-SQL)
Завершает одну из сторон существующего диалога.
Синтаксис
END CONVERSATION conversation_handle
[ [ WITH ERROR = failure_code DESCRIPTION = 'failure_text' ]
| [ WITH CLEANUP ]
]
[ ; ]
Аргументы
conversation_handle
Дескриптор завершаемого диалога.WITH ERROR = failure_code
Код ошибки. Аргумент failure_code имеет тип int. Код ошибки — это определяемое пользователем число, которое включается в сообщение об ошибке, отсылаемое другой стороне диалога. Код ошибки должен быть больше 0.DESCRIPTION = failure_text
Сообщение об ошибке. Аргумент failure_text имеет тип nvarchar(3000). Текст ошибки — это определяемый пользователем текст, который включается в сообщение об ошибке, отсылаемое другой стороне диалога.WITH CLEANUP
Удаляет все сообщения и записи представлений каталога для одной стороны диалога, которая не может завершиться нормально. Другая сторона не оповещается об этой очистке. Microsoft SQL Server удаляет конечную точку диалога, все сообщения диалога в очереди передачи и все сообщения диалога в очереди обслуживания. Администраторы могут использовать этот параметр для удаления диалогов, которые не могут быть нормально завершены. Например, если удаленная служба безвозвратно удалена, администратор может использовать параметр WITH CLEANUP для удаления диалогов, работающих с этой службой. Не следует использовать параметр WITH CLEANUP в коде приложения компонента Service Broker. Если инструкция END CONVERSATION WITH CLEANUP будет запущена до того, как получающая конечная точка подтвердит получение сообщения, то отправляющая конечная точка пошлет сообщение повторно. Потенциально это может вызвать повторный запуск диалога.
Замечания
Завершение диалога блокирует группу сообщений, к которой относится указанный аргумент conversation_handle. При завершении диалога компонент Service Broker удаляет из очереди обслуживания все сообщения, относящиеся к этому диалогу.
После того как диалог завершен, приложение больше не может отправлять и получать сообщения. Оба участника диалога должны вызвать инструкцию END CONVERSATION для его завершения. Если компонент Service Broker не получил от второго участника ни сообщения об окончании диалога, ни сообщения об ошибке, то компонент Service Broker уведомляет его о том, что диалог завершен. В этом случае, несмотря на то, что дескриптор диалога уже недействителен, конечная точка диалога остается активной до тех пор, пока экземпляр, на котором находится служба, не подтвердит сообщение.
Если компонент Service Broker еще не обработал сообщение об окончании диалога или ошибке, то компонент Service Broker уведомляет удаленного участника, что диалог завершен. Какие именно сообщения компонент Service Broker отправляет удаленной службе, зависит от указанных параметров:
Если диалог завершается без ошибок, но диалог с удаленной службой еще активен, компонент Service Broker отправляет ей сообщение типа https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog. Компонент Service Broker добавляет это сообщение в конец очереди передачи в порядке создания диалогов. Прежде чем передать это сообщение, компонент Service Broker отправляет все сообщения для этого диалога, которые находятся в очереди передачи.
Если диалог завершается с ошибкой, а диалог с удаленной службой еще активен, компонент Service Broker отправляет ей сообщение типа https://schemas.microsoft.com/SQL/ServiceBroker/Error. Компонент Service Broker удаляет из очереди передачи все сообщения, относящиеся к этому диалогу.
Предложение WITH CLEANUP позволяет администратору базы данных удалять диалоги, которые не могут быть завершены нормальным способом. Этот параметр удаляет все сообщения и элементы представления каталога для данного диалога. Обратите внимание, что в этом случае удаленная сторона диалога не получает никакого сигнала о том, что диалог завершен, и не сможет получить сообщения, которые были отправлены приложением, но еще не были переданы по сети. Старайтесь не пользоваться этим параметром, если диалог может быть завершен нормально.
После завершения диалога, инструкция SEND языка Transact-SQL, в которой указан дескриптор диалога, вызовет ошибку Transact-SQL. Если сообщения для данного диалога поступают с противоположной стороны, компонент Service Broker отбрасывает их.
Если на момент завершения диалога у удаленной службы остались неотправленные сообщения, они будут удалены. Это не рассматривается как ошибка, и удаленная служба не получит уведомления о том, что сообщения удалены.
Код ошибки, указанный в предложении WITH ERROR, должен быть положительным числом. Отрицательные числа зарезервированы для сообщений об ошибках компонента Service Broker. Дополнительные сведения о сообщениях об ошибках компонента Service Broker см. в разделе Системные сообщения компонента Service Broker.
Инструкция END CONVERSATION не может применяться в пользовательской функции.
Разрешения
Для завершения активного диалога текущий пользователь должен быть его владельцем, членом предопределенной роли сервера sysadmin или предопределенной роли базы данных db_owner.
Член предопределенной роли сервера sysadmin или предопределенной роли базы данных db_owner может указывать предложение WITH CLEANUP для удаления метаданных диалога, который уже завершен.
Примеры
А. Завершение диалога
Следующий пример завершает диалог, определяемый дескриптором @dialog_handle.
END CONVERSATION @dialog_handle ;
Б. Завершение диалога с ошибкой
В следующем примере диалог, определяемый дескриптором @dialog_handle, завершается с ошибкой, если обрабатываемая инструкция сообщила об ошибке. Обратите внимание, что этот упрощенный подход к обработке ошибок может не подойти для некоторых приложений.
DECLARE @dialog_handle UNIQUEIDENTIFIER,
@ErrorSave INT,
@ErrorDesc NVARCHAR(100) ;
BEGIN TRANSACTION ;
<receive and process message>
SET @ErrorSave = @@ERROR ;
IF (@ErrorSave <> 0)
BEGIN
ROLLBACK TRANSACTION ;
SET @ErrorDesc = N'An error has occurred.' ;
END CONVERSATION @dialog_handle
WITH ERROR = @ErrorSave DESCRIPTION = @ErrorDesc ;
END
ELSE
COMMIT TRANSACTION ;
В. Очистка диалога, который не может быть нормально завершен
В следующем примере завершается диалог, определяемый дескриптором @dialog_handle. SQL Server немедленно удаляет все сообщения из очереди обслуживания и очереди передачи, не уведомляя об этом удаленную службу. Поскольку при завершении диалога с очисткой удаленная служба не уведомляется, этот способ следует использовать только в тех случаях, когда удаленная служба недоступна и не может получить сообщение EndDialog или Error.
END CONVERSATION @dialog_handle WITH CLEANUP ;