SQL Server2005中的Service Broker

来源:互联网 发布:为什么淘宝分享打不开 编辑:程序博客网 时间:2024/05/17 01:52

Service Broker:微软提高的比较简单的消息中间件。

具体操作可以通过Management Studio下进行查看.

【用户数据库-Service Broker-消息类型/约定/服务】

搭建底层结构:

 

-- 创建消息类型

CREATE MESSAGE TYPE [//AW/EMail/CustomerDetails] --消息类型名称

VALIDATION = WELL_FORMED_XML --消息类型

 

-- 创建协定

CREATE CONTRACT [//AW/EMail/SendCustomerDetails] --协定名称

(

    [//AW/EMail/CustomerDetails] --消息类型名称

    SENT BY INITIATOR --会话发起方发送,接受方不能回复

)

将来如果通信双方采用这个协定,接受方接受的类型只能是指定的类型,如果接受到其它类型,视为非法消息。

 

-- 创建队列

--队列不属于应用程序,属于Service Broker机制架构

--给发送发使用的队列

CREATE QUEUE CustomerSvc.NewCustomerQueue  --架构名.队列名

WITH STATUS = ON    --让队列处于激活状态

 

--给接受方使用的队列

CREATE QUEUE EMailSvc.NewCustomerEmailQueue

WITH STATUS = OFF

--如果将状态置为off,说明现在应用程序还不能通过队列接受消息。

 

-- 为发送方创建服务

--服务绑定队列,将来服务将从这个队列中接受消息

CREATE SERVICE [//AW/Sales/CustomerService]

ON QUEUE CustomerSvc.NewCustomerQueue

 

--为接受方创建服务

CREATE SERVICE [//AW/EMail/EmailService]

ON QUEUE EMailSvc.NewCustomerEmailQueue

([//AW/EMail/SendCustomerDetails])

利用底层基础结构:

―――――――――――――――――――――――――――――――――――――――――

--发送方存储过程

--web应用程序调用的存储过程

--把客户的基本信息形成电子邮件,发送给消息接受方

CREATE PROCEDURE  CustomerSvc.uspEmailNewCustomer

    @firstName nvarchar(50),

    @lastName nvarchar(50),

    @emailAddress nvarchar(50)

AS

BEGIN

    SET NOCOUNT ON;

 

    -- 创建传送到邮件发送服务的消息体

    DECLARE @message xml

 

    SET @message = NCHAR(0xFEFF)

    + '<Customer>'

    + '<CustomerName>' + @firstName + ' ' + @lastName + '</CustomerName>'

    + '<EmailAddress>' + @emailAddress + '</EmailAddress>'

    + '</Customer>'

 

DECLARE @dialogHandle UNIQUEIDENTIFIER

 

--建立一个会话,

    BEGIN DIALOG @dialogHandle                    --返回建立的会话句柄

    FROM SERVICE [//AW/Sales/CustomerService]     --发送服务器

    TO SERVICE '//AW/EMail/EmailService'           --接受服务器

    ON CONTRACT [//AW/EMail/SendCustomerDetails]; --会话满足的协定

   

--向会话@dialogHandle发送消息

    SEND ON CONVERSATION @dialogHandle

    MESSAGE TYPE [//AW/EMail/CustomerDetails] (@message)--消息类型+消息内容

    --结束会话,完成发送方任务

    END CONVERSATION @dialogHandle

END;

―――――――――――――――――――――――――――――――――――――――――

--接受方存储过程

 

CREATE PROCEDURE EMailSvc.uspSendCustomerEmail

WITH EXECUTE AS OWNER

AS

BEGIN

    SET NOCOUNT ON;

 

    DECLARE @conversation UNIQUEIDENTIFIER

    DECLARE @msg NVARCHAR(MAX)

    DECLARE @msgType NVARCHAR(256)

 

    ;RECEIVE TOP(1)                          --取最前面的消息

        @conversation = conversation_handle,    --句柄

        @msgType = message_type_name,           --消息类型

        @msg = message_body                     --消息正文(发送方发送的XML数据)

    FROM AdventureWorks.EMailSvc.NewCustomerEmailQueue

 

    IF (@@ROWCOUNT = 0) RETURN                  --消息队列为空

 

    IF (@msgType = '//AW/EMail/CustomerDetails') --消息不为空,判断消息类型是否正确

        BEGIN

 

            -- OPENXML()解析XML,获取其中的值(提取邮件地址)

            DECLARE @emailAddress nvarchar(30)  --限制email长度为30,可以修改此处

            DECLARE @hDoc int

            EXECUTE sp_xml_preparedocument @hdoc OUTPUT, @msg

            SELECT @emailAddress = EmailAddress   --存放客户邮件地址

            FROM OPENXML(@hDoc, 'Customer', 2)

            WITH

            (EmailAddress nvarchar(30))

            EXECUTE sp_xml_removedocument @hDoc

 

            -- 系统存储过程(msdb.dbo.sp_send_dbmail发送邮件

            EXECUTE msdb.dbo.sp_send_dbmail @recipients =

@emailAddress,

              @subject = 'Welcome to Adventure Works',

              @body = 'We would like to welcome you to Adventure Works.'

           

 

            -- Log the email

            INSERT INTO AdventureWorks.EMailSvc.EmailLog

                (Date, [Event], CustomerData)

            VALUES

                (getdate(), 'Email sent to ' + @emailAddress, @msg);

        END

 

    ELSE IF (@msgType = 'http://schemas.microsoft.com/SQL/ServiceBroker/Error') OR

        (@msgType = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')

       

 

        END CONVERSATION @conversation

 

ELSE                --接受错误的消息,结束会话

BEGIN

            END CONVERSATION @conversation

            WITH ERROR = 500 DESCRIPTION = 'Invalid message type.';

 

            INSERT INTO AdventureWorks.EMailSvc.EmailLog

(Date, [Event], CustomerData)

            VALUES (getdate(), 'Invalid message type', @msg);

        END

END;

 

―――――――――――――――――――――――――――――――――――――――――

--更改接受方的队列状态

 

ALTER QUEUE EMailSvc.NewCustomerEmailQueue

WITH STATUS = ON,

     ACTIVATION (  --接受方的应用程序由队列来激活的,

--如果队列检测到队列里面有消息,就会调用接受方的应用程序

        STATUS = ON,

        --指定被激活的程序

        PROCEDURE_NAME = AdventureWorks.EMailSvc.uspSendCustomerEmail,

        MAX_QUEUE_READERS = 5,

        EXECUTE AS OWNER)

―――――――――――――――――――――――――――――――――――――――――

 

--模拟web应用程序,调用存储过程

EXEC AdventureWorks.CustomerSvc.uspEmailNewCustomer

    @firstName = 'Greg',

    @lastName = 'Guzik',

    @emailAddress = 'student@adventure-works.com'

 

SELECT * FROM AdventureWorks.EMailSvc.EmailLog

 

 

原创粉丝点击