BEGIN DIALOG CONVERSATION (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。
- FROM SERVICE initiator_service_name
指定启动对话的服务。 指定的名称必须是当前数据库中的服务的名称。 为发起方服务指定的队列将接收由目标服务返回的消息,以及 Service Broker 为此会话创建的消息。
- TO 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() ;
有关 Service Broker 标识的详细信息,请参阅管理 Service Broker 标识。
- 'CURRENT DATABASE'
指定会话使用当前数据库的 service_broker_guid。
- ON CONTRACT contract_name
指定此会话遵循的约定。 当前数据库中必须有该约定。 如果目标服务不接受遵循指定约定的新会话,则 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 数据类型的最大值。
ENCRYPTION
将此对话发送和接收的消息向 Microsoft SQL Server 实例外发送时,是否必须对消息加密。 必须加密的对话是安全对话**。 如果 ENCRYPTION = ON,但未配置支持加密所需的证书,则 Service Broker 将返回针对该会话的错误消息。 ENCRYPTION = OFF 时,如果为 target_service_name 配置了远程服务绑定,则使用加密;否则,发送消息时不加密。 如果未使用此子句,则默认值为 ON。 有关对话安全性的详细信息,请参阅Service Broker 对话安全模式。注意: 在任何情况下,都不对同一个 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 在用户定义函数中无效。
权限
若要启动对话,则当前的用户对于在该命令的 FROM 子句中指定的服务的队列必须有 RECEIVE 权限,对于指定的约定有 REFERENCES 权限。
示例
A. 启动对话
以下实例会启动一个对话会话,并将对话的标识符存储于 @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
秒内未关闭此对话,则 Broker 将结束此对话并返回错误。
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 ;
C. 启动带特定 broker 实例的对话
以下实例将启动一个对话会话,并将对话的标识符存储于 @dialog_handle
。 //Adventure-Works.com/ExpenseClient
服务是对话的发起方,//Adventure-Works.com/Expenses
服务是对话的目标。 对话遵循约定 //Adventure-Works.com/Expenses/ExpenseSubmission
。 Broker 将此对话的消息路由到由 GUID a326e034-d4cf-4e8b-8d98-4d7e1926c904.
标识的 Broker。
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
。 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 ;
E. 启动带显式生存期的对话,并将此对话关联到现有会话
以下实例将启动一个对话会话,并将对话的标识符存储于 @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 ;
请参阅
参考
BEGIN CONVERSATION TIMER (Transact-SQL)
END CONVERSATION (Transact-SQL)
MOVE CONVERSATION (Transact-SQL)
sys.conversation_endpoints (Transact-SQL)
其他资源
Service Broker 教程
会话组
Conversation Group Locks
对话会话