新聞中心
導(dǎo)讀:本文主要涉及Service Broker的基本概念及建立一個(gè)Service Broker應(yīng)用程序的基本步驟。

創(chuàng)新互聯(lián)始終堅(jiān)持【策劃先行,效果至上】的經(jīng)營(yíng)理念,通過(guò)多達(dá)十多年累計(jì)超上千家客戶(hù)的網(wǎng)站建設(shè)總結(jié)了一套系統(tǒng)有效的全網(wǎng)推廣解決方案,現(xiàn)已廣泛運(yùn)用于各行各業(yè)的客戶(hù),其中包括:成都銅雕雕塑等企業(yè),備受客戶(hù)贊譽(yù)。
一、前言:
Service Broker為SQL Server提供消息隊(duì)列,這提供了從數(shù)據(jù)庫(kù)中發(fā)送異步事務(wù)性消息隊(duì)列的方法。Service Broker消息可以保證以適當(dāng)?shù)捻樞蚧蛟嫉陌l(fā)送順序不重復(fù)地一次性接收。并且因?yàn)閮?nèi)建在SQL Server中,這些消息在數(shù)據(jù)庫(kù)發(fā)生故障時(shí)是可以恢復(fù)的,也可以隨數(shù)據(jù)庫(kù)一起備份。在SQL Server 2008中,還引入了使用Create Broker Priority命令對(duì)會(huì)話(huà)設(shè)定優(yōu)先級(jí),可以對(duì)重要的或不重要的會(huì)話(huà)進(jìn)行優(yōu)先級(jí)設(shè)定,以保證消息合理地處理。
本文假定一個(gè)在線(xiàn)數(shù)據(jù)庫(kù)BookStore中存儲(chǔ)了一些業(yè)務(wù)訂單。我們使用Service Broker應(yīng)用程序?qū)⑾l(fā)送到另一個(gè)數(shù)據(jù)庫(kù)BookDistribution,該數(shù)據(jù)庫(kù)是分離的應(yīng)用程序調(diào)用,該應(yīng)用程序控制倉(cāng)庫(kù)入庫(kù)和出庫(kù)交付, 并返回消息給BookStore。
創(chuàng)建Service Broker應(yīng)用程序大體步驟如下:
1、定義希望應(yīng)用程序執(zhí)行的異步任務(wù)。
2、確定Service Broker的發(fā)起方服務(wù)和目標(biāo)服務(wù)是否創(chuàng)建在同一個(gè)SQL Server實(shí)例中。如果是兩個(gè)實(shí)例,實(shí)例間的通信還需要?jiǎng)?chuàng)建經(jīng)過(guò)證書(shū)認(rèn)證或NT安全的身份認(rèn)證,并且要?jiǎng)?chuàng)建端點(diǎn)、路由以及對(duì)話(huà)安全模式。
3、如果沒(méi)有啟用,則在多方參與的數(shù)據(jù)庫(kù)中使用Alter Database命令設(shè)置Enable_broker以及Truseworthy數(shù)據(jù)庫(kù)選項(xiàng)。
4、為所有多方參與的數(shù)據(jù)庫(kù)創(chuàng)建數(shù)據(jù)庫(kù)主密鑰。
5、創(chuàng)建希望在服務(wù)之間發(fā)送的消息類(lèi)型。
6、創(chuàng)建契約(Contract)來(lái)定義可以由發(fā)起方發(fā)送的各種消息以及由目標(biāo)發(fā)送的消息類(lèi)型的種類(lèi)。
7、同時(shí)在兩方參與的數(shù)據(jù)庫(kù)中創(chuàng)建用于保存消息的隊(duì)列。
8、同時(shí)在綁定特定約定到特定隊(duì)列的多方參與的數(shù)據(jù)庫(kù)中創(chuàng)建服務(wù)。
二、實(shí)例
下面我們通過(guò)一個(gè)示例來(lái)實(shí)現(xiàn)以上步驟:
(一)、啟用數(shù)據(jù)庫(kù)的Service Broker活動(dòng)
--
Enabling Databases for Service Broker Activity
USE
master
GO
IF
NOT
EXISTS
(
SELECT
name
FROM
sys.databases
WHERE
name
=
'
BookStore
'
)
CREATE
DATABASE
BookStore
GO
IF
NOT
EXISTS
(
SELECT
name
FROM
sys.databases
WHERE
name
=
'
BookDistribution
'
)
CREATE
DATABASE
BookDistribution
GO
ALTER
DATABASE
BookStore
SET
ENABLE_BROKER
GO
ALTER
DATABASE
BookStore
SET
TRUSTWORTHY
ON
GO
ALTER
DATABASE
BookDistribution
SET
ENABLE_BROKER
GO
ALTER
DATABASE
BookDistribution
SET
TRUSTWORTHY
ON
(二)、創(chuàng)建數(shù)據(jù)庫(kù)主密鑰
--
Creating the DatabaseMaster Key for Encryption
USE
BookStore
GO
CREATE
MASTER
KEY
ENCRYPTION
BY
PASSWORD
=
'
I5Q7w1d3
'
GO
USE
BookDistribution
GO
CREATE
MASTER
KEY
ENCRYPTION
BY
PASSWORD
=
'
D1J3q5z8X6y4
'
GO
(三)、管理消息類(lèi)型
使用CREATE MESSAGE TYPE(http://msdn.microsoft.com/en-us/library/ms187744.aspx)命令,
--
Managing Message Types
Use
BookStore
GO
--
發(fā)送圖書(shū)訂單的消息類(lèi)型
CREATE
MESSAGE TYPE
[
//SackConsulting/SendBookOrder
]
VALIDATION
=
WELL_FORMED_XML
GO
--
目標(biāo)數(shù)據(jù)庫(kù)發(fā)送的消息類(lèi)型
CREATE
MESSAGE TYPE
[
//SackConsulting/BookOrderReceived
]
VALIDATION
=
WELL_FORMED_XML
GO
--
執(zhí)行同樣的定義
Use
BookDistribution
GO
--
發(fā)送圖書(shū)訂單的消息類(lèi)型
CREATE
MESSAGE TYPE
[
//SackConsulting/SendBookOrder
]
VALIDATION
=
WELL_FORMED_XML
GO
--
目標(biāo)數(shù)據(jù)庫(kù)發(fā)送的消息類(lèi)型
CREATE
MESSAGE TYPE
[
//SackConsulting/BookOrderReceived
]
VALIDATION
=
WELL_FORMED_XML
GO
--注意,此處沒(méi)有定義消息的內(nèi)容。實(shí)際的消息是消息類(lèi)型的實(shí)例。
(四)、創(chuàng)建契約(Contract)
使用Create Contract(http://msdn.microsoft.com/en-us/library/ms178528.aspx)
--
Creating Contracts
Use
BookStore
GO
CREATE
CONTRACT
[
//SackConsulting/BookOrderContract
]
(
[
//SackConsulting/SendBookOrder
]
SENT
BY
INITIATOR,
[
//SackConsulting/BookOrderReceived
]
SENT
BY
TARGET
)
GO
USE
BookDistribution
GO
CREATE
CONTRACT
[
//SackConsulting/BookOrderContract
]
(
[
//SackConsulting/SendBookOrder
]
SENT
BY
INITIATOR,
[
//SackConsulting/BookOrderReceived
]
SENT
BY
TARGET
)
GO
--發(fā)起方和目標(biāo)的定義必須相同
(五)、創(chuàng)建隊(duì)列
隊(duì)列用來(lái)保存數(shù)據(jù)。使用命令Create queue(http://msdn.microsoft.com/en-us/library/ms190495.aspx)
--
Creating Queues
Use
BookStore
GO
--
保存BookDistribution過(guò)來(lái)的消息
CREATE
QUEUE BookStoreQueue
WITH
STATUS
=
ON
GO
USE
BookDistribution
GO
--
保存BookStore過(guò)來(lái)的消息
CREATE
QUEUE BookDistributionQueue
WITH
STATUS
=
ON
GO
(六)、創(chuàng)建服務(wù)
服務(wù)定義端點(diǎn),然后使用它來(lái)將消息隊(duì)列綁定到一個(gè)或多個(gè)契約上。服務(wù)使用隊(duì)列和契約來(lái)定義一個(gè)或一組任務(wù)。有點(diǎn)拗口,是不是?
服務(wù)是消息的發(fā)起方和接收方強(qiáng)制約定的規(guī)則,并將消息路由到正確的序列。
使用Create Service(http://msdn.microsoft.com/en-us/library/ms190332.aspx)命令。
--
Creating Services
Use
BookStore
GO
CREATE
SERVICE
[
//SackConsulting/BookOrderService
]
ON
QUEUE dbo.BookStoreQueue
--
指定的隊(duì)列綁定到契約
(
[
//SackConsulting/BookOrderContract
]
)
GO
USE
BookDistribution
GO
CREATE
SERVICE
[
//SackConsulting/BookDistributionService
]
ON
QUEUE dbo.BookDistributionQueue
--
指定的隊(duì)列綁定到契約
(
[
//SackConsulting/BookOrderContract
]
)
GO
(七)、啟動(dòng)對(duì)話(huà)
對(duì)話(huà)會(huì)話(huà)(dialog conservation)是在服務(wù)之間進(jìn)行消息交換的操作。
使用Begin Dialog Conversation(http://msdn.microsoft.com/en-us/library/ms187377.aspx) 命令創(chuàng)建新的會(huì)話(huà)。使用Send(http://msdn.microsoft.com/en-us/library/ms188407.aspx)來(lái)發(fā)送消息。使用End Conversation命令(http://msdn.microsoft.com/en-us/library/ms177521.aspx)結(jié)束會(huì)話(huà)。
--
Initiating a Dialog
Use
BookStore
GO
--
保存會(huì)話(huà)句柄和訂單信息
DECLARE
@Conv_Handler
uniqueidentifier
DECLARE
@OrderMsg
xml;
BEGIN
DIALOG CONVERSATION
@Conv_Handler
--
創(chuàng)建會(huì)話(huà)
FROM
SERVICE
[
//SackConsulting/BookOrderService
]
TO
SERVICE
'
//SackConsulting/BookDistributionService
'
ON
CONTRACT
[
//SackConsulting/BookOrderContract
]
;
SET
@OrderMsg
=
'
'
;
SEND
ON
CONVERSATION
@Conv_Handler
--
發(fā)送到BookDistribution數(shù)據(jù)庫(kù)的隊(duì)列中
MESSAGE TYPE
[
//SackConsulting/SendBookOrder
]
(
@OrderMsg
);
(八)、查詢(xún)隊(duì)列中傳入的消息
--
Querying the Queue for IncomingMessages
USE
BookDistribution
GO
SELECT
message_type_name,
CAST
(message_body
as
xml) message,
queuing_order, conversation_handle, conversation_group_id
FROM
dbo.BookDistributionQueue
查詢(xún)結(jié)果:
(九)、檢索并響應(yīng)消息
使用Receive語(yǔ)句(http://msdn.microsoft.com/en-us/library/ms186963.aspx)從隊(duì)列中讀取行(消息),也可以刪除已經(jīng)讀取的消息。Receive的結(jié)果可以填充到常規(guī)表中,也可以在局部變量中執(zhí)行其他操作,或發(fā)送到其他service Broker消息。如果消息是XML數(shù)據(jù)類(lèi)型的消息,則可以直接借助TSQL的XQuery來(lái)操作。
--
Receiving and Responding to aMessage
USE
BookDistribution
GO
--
創(chuàng)建一個(gè)表存放接收到的訂單信息
CREATE
TABLE
dbo.BookOrderReceived
(BookOrderReceivedID
int
IDENTITY
(
1
,
1
)
NOT
NULL
,
conversation_handle
uniqueidentifier
NOT
NULL
,
conversation_group_id
uniqueidentifier
NOT
NULL
,
message_body xml
NOT
NULL
)
GO
--
聲明變量
DECLARE
@Conv_Handler
uniqueidentifier
DECLARE
@Conv_Group
uniqueidentifier
DECLARE
@OrderMsg
xml
DECLARE
@TextResponseMsg
varchar
(
8000
)
DECLARE
@ResponseMsg
xml
DECLARE
@OrderID
int
;
--
從隊(duì)列中獲取消息,將接收值賦于局部變量
RECEIVE
TOP
(
1
)
@OrderMsg
=
message_body,
--
TOP指定最多一條消息
@Conv_Handler
=
conversation_handle,
@Conv_Group
=
conversation_group_id
FROM
dbo.BookDistributionQueue;
--
將變量值插入表中
INSERT
dbo.BookOrderReceived
(conversation_handle, conversation_group_id, message_body)
VALUES
(
@Conv_Handler
,
@Conv_Group
,
@OrderMsg
)
--
使用XQuery進(jìn)行抽取以響應(yīng)消息訂單
SELECT
@OrderID
=
@OrderMsg
.value(
'
(/order/@id)[1]
'
,
'
int
'
)
SELECT
@TextResponseMsg
=
'
'
;
SELECT
@ResponseMsg
=
CAST
(
@TextResponseMsg
as
xml);
--
使用既有的會(huì)話(huà)句柄,發(fā)送響應(yīng)消息到發(fā)起方
SEND
ON
CONVERSATION
@Conv_Handler
MESSAGE TYPE
[
//SackConsulting/BookOrderReceived
]
(十)、結(jié)束會(huì)話(huà)
--
Ending a Conversation
USE
BookStore
GO
--
創(chuàng)建訂單確認(rèn)表
CREATE
TABLE
dbo.BookOrderConfirmation
(BookOrderConfirmationID
int
IDENTITY
(
1
,
1
)
NOT
NULL
,
conversation_handle
uniqueidentifier
NOT
NULL
,
DateReceived
datetime
NOT
NULL
DEFAULT
GETDATE
(),
message_body xml
NOT
NULL
)
DECLARE
@Conv_Handler
uniqueidentifier
DECLARE
@Conv_Group
uniqueidentifier
DECLARE
@OrderMsg
xml
DECLARE
@TextResponseMsg
varchar
(
8000
);
RECEIVE
TOP
(
1
)
@Conv_Handler
=
conversation_handle,
@OrderMsg
=
message_body
FROM
dbo.BookStoreQueue
INSERT
dbo.BookOrderConfirmation
(conversation_handle, message_body)
VALUES
(
@Conv_Handler
,
@OrderMsg
);
END
CONVERSATION
@Conv_Handler
;
GO
USE
BookDistribution
GO
DECLARE
@Conv_Handler
uniqueidentifier
DECLARE
@Conv_Group
uniqueidentifier
DECLARE
@OrderMsg
xml
DECLARE
@message_type_name
nvarchar
(
256
);
RECEIVE
TOP
(
1
)
@Conv_Handler
=
conversation_handle,
@OrderMsg
=
message_body,
@message_type_name
=
message_type_name
FROM
dbo.BookDistributionQueue
--
雙方必須都結(jié)束會(huì)話(huà)
IF
@message_type_name
=
'
http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog
'
BEGIN
END
CONVERSATION
@Conv_Handler
;
END
--查詢(xún)會(huì)話(huà)狀態(tài)
SELECT
state_desc, conversation_handle
FROM
sys.conversation_endpoints
三、小結(jié)
本文通過(guò)一個(gè)實(shí)例演示了一個(gè)用來(lái)發(fā)送圖書(shū)訂單消息分發(fā)控制數(shù)據(jù)庫(kù)的簡(jiǎn)單的消息交換應(yīng)用程序。發(fā)起方發(fā)送圖書(shū)訂單,發(fā)回一個(gè)響應(yīng),并在兩個(gè)數(shù)據(jù)庫(kù)上使用END Conservation結(jié)束會(huì)話(huà)?,F(xiàn)實(shí)場(chǎng)景中可以轉(zhuǎn)換為其他消息類(lèi)型、契約、服務(wù)和隊(duì)列。合理運(yùn)用Service Broker應(yīng)用程序的異步特性可以防止因應(yīng)用程序掛起而導(dǎo)致業(yè)務(wù)系統(tǒng)產(chǎn)生瓶頸。
原文鏈接:http://www.cnblogs.com/downmoon/archive/2011/04/05/2005900.html
【編輯推薦】
- 簡(jiǎn)述Service Broker事件通知功能
- 一個(gè)Excel導(dǎo)入SQL Server的例子
- 優(yōu)化你的DiscuzNT,讓它跑起來(lái)
- 淺述當(dāng)前模式讀與一致性讀續(xù)
- 淺述當(dāng)前模式讀與一致性讀的區(qū)別
新聞名稱(chēng):ServiceBroker基礎(chǔ)應(yīng)用(上)
網(wǎng)頁(yè)地址:http://m.fisionsoft.com.cn/article/cdegjih.html


咨詢(xún)
建站咨詢(xún)
