首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server Service Broker 異步訊息傳遞實戰:跨資料庫通訊完整範例

     編輯:關於SqlServer

架構概覽

本範例示範同一 SQL Server 執行個體內,兩個資料庫間透過 Service Broker 實現異步訊息傳遞:

  • HelloWorldDB:目標資料庫(接收端/服務提供者)
  • DotNetFun2:發起端資料庫(發送者/消費者)

前置條件:已建立訊息類型、合約、佇列、路由等基礎物件。參考《SQL Server 2005 Service Broker 教學》建立 XMLMessage、XMLContract、SendingQueue、ReceivingQueue 等。

步驟 1:建立接收端儲存程序(內部服務程式)

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 避免忙碌等待
  • 單次處理一筆訊息,配合佇列保留設定決定是否移除
  • 交易包裹確保訊息處理原子性

步驟 2:啟用目標佇列自動激活

USE HelloWorldDB;
GO

ALTER QUEUE [ReceivingQueue] WITH
    ACTIVATION (
        STATUS = ON,
        PROCEDURE_NAME = [HelloWorldResponder],
        MAX_QUEUE_READERS = 4,      -- 最多 4 個並行讀取器
        EXECUTE AS SELF             -- 以傳入對話的使用者身分執行
    );

步驟 3:發起端發送訊息

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_guid
  • 取得目標資料庫 GUID:SELECT service_broker_guid FROM sys.databases WHERE database_id = DB_ID('HelloWorldDB')

步驟 4:驗證回覆訊息

-- 檢視發送佇列中的回覆
SELECT CAST(message_body AS XML) FROM SendingQueue;

RECEIVE message_type_name, CAST(message_body AS XML)
FROM SendingQueue;

步驟 5:監控對話端點狀態

-- 雙端皆可查詢
SELECT * FROM sys.conversation_endpoints;

關鍵欄位:state(STARTED/ENDED/ERROR)、far_service、lifetime。

架構優勢

  • 解耦:發送者不需等待接收者處理完成
  • 可靠性:訊息持久化於佇列,重啟不遺失
  • 擴展性:MAX_QUEUE_READERS 控制並行度
  • 跨資料庫/跨執行個體:透過路由與憑證支援分散式部署

Service Broker 是 SQL Server 內建的企業級訊息總線,善用它能大幅簡化非同步處理架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved