Service Broker 為 SQL Server 內建異步訊息隊列引擎,提供保證順序、不重複、可恢復、可備份的交易性訊息傳遞。SQL 2008 新增 CREATE BROKER PRIORITY 支援會話優先級。本文以「書店訂單 → 配送中心」跨資料庫異步處理為例,完整演示從啟用到對話結束的標準化建構流程。
ALTER DATABASE BookStore SET ENABLE_BROKER;
ALTER DATABASE BookStore SET TRUSTWORTHY ON;
ALTER DATABASE BookDistribution SET ENABLE_BROKER;
ALTER DATABASE BookDistribution SET TRUSTWORTHY ON;
USE BookStore; CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'I5Q7w1d3';
USE BookDistribution; CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'D1J3q5z8X6y4';
-- 兩個資料庫完全相同定義
CREATE MESSAGE TYPE [//SackConsulting/SendBookOrder] VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE [//SackConsulting/BookOrderReceived] VALIDATION = WELL_FORMED_XML;
CREATE CONTRACT [//SackConsulting/BookOrderContract]
(
[//SackConsulting/SendBookOrder] SENT BY INITIATOR,
[//SackConsulting/BookOrderReceived] SENT BY TARGET
);
USE BookStore; CREATE QUEUE BookStoreQueue WITH STATUS=ON;
USE BookDistribution; CREATE QUEUE BookDistributionQueue WITH STATUS=ON;
USE BookStore;
CREATE SERVICE [//SackConsulting/BookOrderService]
ON QUEUE dbo.BookStoreQueue
([//SackConsulting/BookOrderContract]);
USE BookDistribution;
CREATE SERVICE [//SackConsulting/BookDistributionService]
ON QUEUE dbo.BookDistributionQueue
([//SackConsulting/BookOrderContract]);
USE BookStore;
DECLARE @Conv_Handler UNIQUEIDENTIFIER, @OrderMsg XML;
BEGIN DIALOG CONVERSATION @Conv_Handler
FROM SERVICE [//SackConsulting/BookOrderService]
TO SERVICE '//SackConsulting/BookDistributionService'
ON CONTRACT [//SackConsulting/BookOrderContract];
SET @OrderMsg = '
';
SEND ON CONVERSATION @Conv_Handler
MESSAGE TYPE [//SackConsulting/SendBookOrder] (@OrderMsg);
USE BookDistribution;
SELECT message_type_name, CAST(message_body AS XML) AS message,
queuing_order, conversation_handle, conversation_group_id
FROM dbo.BookDistributionQueue;

USE BookDistribution;
CREATE TABLE dbo.BookOrderReceived (...);
DECLARE @Conv_Handler UNIQUEIDENTIFIER, @Conv_Group UNIQUEIDENTIFIER,
@OrderMsg XML, @TextResponseMsg VARCHAR(8000), @ResponseMsg XML, @OrderID INT;
RECEIVE TOP(1)
@OrderMsg = message_body,
@Conv_Handler = conversation_handle,
@Conv_Group = conversation_group_id
FROM dbo.BookDistributionQueue;
INSERT dbo.BookOrderReceived (...) VALUES (@Conv_Handler, @Conv_Group, @OrderMsg);
-- XQuery 擷取訂單 ID 並構建回覆
SELECT @OrderID = @OrderMsg.value('(/order/@id)[1]', 'int');
SET @TextResponseMsg = ' ';
SET @ResponseMsg = CAST(@TextResponseMsg AS XML);
SEND ON CONVERSATION @Conv_Handler
MESSAGE TYPE [//SackConsulting/BookOrderReceived] (@ResponseMsg);
-- 啟動端接收確認並結束
USE BookStore;
RECEIVE TOP(1) @Conv_Handler = conversation_handle, @OrderMsg = message_body
FROM dbo.BookStoreQueue;
INSERT dbo.BookOrderConfirmation (...) VALUES (@Conv_Handler, @OrderMsg);
END CONVERSATION @Conv_Handler;
-- 目標端接收 EndDialog 訊息並結束
USE BookDistribution;
RECEIVE TOP(1) @Conv_Handler = conversation_handle, @message_type_name = message_type_name
FROM dbo.BookDistributionQueue;
IF @message_type_name = 'https://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
END CONVERSATION @Conv_Handler;
SELECT state_desc, conversation_handle FROM sys.conversation_endpoints;

善用 Service Broker 異步特性,可有效消除業務系統因同步等待產生的效能瓶頸,構建彈性、可擴展的企業級應用架構。