本範例示範同一 SQL Server 執行個體內,兩個資料庫間透過 Service Broker 實現異步訊息傳遞:
前置條件:已建立訊息類型、合約、佇列、路由等基礎物件。參考《SQL Server 2005 Service Broker 教學》建立
XMLMessage、XMLContract、SendingQueue、ReceivingQueue等。
USE HelloWorldDB;
GO
ALTER PROCEDURE HelloWorldResponder
AS
BEGIN
DECLARE @conversationHandle UNIQUEIDENTIFIER,
@message_body NVARCHAR(MAX),
@message_type_name SYSNAME;
WHILE (1 = 1)
BEGIN
BEGIN TRANSACTION;
-- 等待訊息最多 1 秒
WAITFOR (
RECEIVE TOP(1)
@message_type_name = message_type_name,
@conversationHandle = conversation_handle,
@message_body = message_body
FROM [ReceivingQueue]
), TIMEOUT 1000;
-- 無訊息則跳出
IF (@@ROWCOUNT <= 0)
BREAK;
-- 處理 XML 訊息並回覆
IF @message_type_name = 'XMLMessage'
BEGIN
SEND ON CONVERSATION @conversationHandle
MESSAGE TYPE XMLMessage
('Hello From Rickie ');
END CONVERSATION @conversationHandle;
END
COMMIT;
END
COMMIT;
END
GO
關鍵點:
WAITFOR (RECEIVE...), TIMEOUT 避免忙碌等待USE HelloWorldDB;
GO
ALTER QUEUE [ReceivingQueue] WITH
ACTIVATION (
STATUS = ON,
PROCEDURE_NAME = [HelloWorldResponder],
MAX_QUEUE_READERS = 4, -- 最多 4 個並行讀取器
EXECUTE AS SELF -- 以傳入對話的使用者身分執行
);
USE DotNetFun2;
GO
DECLARE @conversationHandle UNIQUEIDENTIFIER;
BEGIN TRANSACTION;
BEGIN DIALOG @conversationHandle
FROM SERVICE [SendingService]
TO SERVICE 'ReceivingService', 'a727462b-52e7-4405-9eee-d19923729790'
ON CONTRACT [XMLContract]
WITH ENCRYPTION = OFF, LIFETIME = 600;
SEND ON CONVERSATION @conversationHandle
MESSAGE TYPE [XMLMessage]
('Welcome to Rickie Lee''s blog, www.cnblogs.com/rickie ');
SELECT * FROM sys.conversation_endpoints;
COMMIT;
關鍵參數:
TO SERVICE 'ReceivingService', 'GUID':目標服務名稱 + 目標資料庫的 service_broker_guidSELECT service_broker_guid FROM sys.databases WHERE database_id = DB_ID('HelloWorldDB')-- 檢視發送佇列中的回覆
SELECT CAST(message_body AS XML) FROM SendingQueue;
RECEIVE message_type_name, CAST(message_body AS XML)
FROM SendingQueue;
-- 雙端皆可查詢
SELECT * FROM sys.conversation_endpoints;
關鍵欄位:state(STARTED/ENDED/ERROR)、far_service、lifetime。
MAX_QUEUE_READERS 控制並行度Service Broker 是 SQL Server 內建的企業級訊息總線,善用它能大幅簡化非同步處理架構。