1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P198 ppt

10 84 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 202,06 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

In response to the arrival of this new message, Service Broker executes a stored procedure associated with a catalog maintenance service for XCatMgmt, known as its service program.. You

Trang 1

Designing a Sample System

The sample messaging system used in this chapter has the following design: an update

stored procedure in AdventureWorks2008.Production.ProductModelstarts up a service

that initiates a conversation with a service in XCatMgmt It does this by sending a message

to the inbound work queue of XCatMgmt When the transaction surrounding the initial

send is complete, Service Broker transmits the message, signaling that a catalog change for

an AdventureWorks Cycles product model is ready for processing

In response to the arrival of this new message, Service Broker executes a stored procedure

associated with a catalog maintenance service for XCatMgmt, known as its service program

This process is known as internal activation; it is internal because the stored procedure

resides in and is activated by SQL Server

Because a Service Broker program might not always be a stored procedure, external

activa-tion is also available when you use event notificaactiva-tion with the QUEUE_ACTIVATIONevent

You can create an event notification service and map it to your Service Broker service and

queue by using syntax such as the following:

CREATE QUEUE NotificationQueue

GO

CREATE SERVICE EventNotificationService

ON QUEUE NotificationQueue

([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])

GO

CREATE EVENT NOTIFICATION NotifyMe

ON QUEUE NotificationQueue FOR QUEUE_ACTIVATION

TO SERVICE ‘EventNotificationService’, ‘broker-instance-guid’

Note that you need to retrieve your database’s Service Broker unique identifier and

replace’broker-instance-guid’with it for the example to work To do this, you run the

following query:

SELECT service_broker_guid

FROM sys.databases

WHERE NAME = ‘AdventureWorks2008’

go

service_broker_guid

-3036906E-8B9E-4266-A8C6-DD4E01B656CA

(1 row(s) affected)

You should keep this query in mind because you need it later in this chapter when you’re

working on service conversations

Let’s return to the sample system’s description When the catalog maintenance service’s

work is done, it sends an acknowledgment message back to the sender’s inbound queue

Trang 2

Service Broker Application

Conversion Group

Dialog (Conversion)

Contract Activation Activation

Service

FIGURE 49.1 Service Broker concepts illustrated

To accomplish everything included in the design so far, you need to represent the

follow-ing kinds of objects in the system:

Two types of messages: one defining product model catalog changes and one for

acknowledgments

Two queues, one for each service

One contract that defines the message flow between the services

Two services, each representing an endpoint in the system

At least one conversation and its related conversation group

The following sections describe how to define and build on all these new constructs, and

you learn how they work together in the orchestration of Service Broker applications

Understanding Service Broker Constructs

To introduce the new Service Broker constructs you’ll be using, Figure 49.1 shows the

interrelations between the constructs described in the upcoming subsections

Figure 49.1 illustrates the fact that a dialog is a conversation between two services These

services exchange typed (or untyped) messages by sending them to queues according to

the rules of a contract Each service can have a service program activated by Service Broker

to receive messages from a queue Every conversation belongs to a conversation group

Messages are always sent with respect to a conversation group One or more conversation

groups make up a Service Broker application

Defining Messages and Choosing a Message Type

For the AdventureWorks2008database to communicate with the XCatMgmtdatabase via

Service Broker, a dialog between two services must take place Within this conversation,

each service sends messages to or receives messages from queues, providing the indirection

needed for the underlying systems to stay loosely coupled

Trang 3

The dialog messages are typed to constrain and (optionally) validate their content You use

the new SQL Server database object MESSAGEto represent a typed message Defining the

messages to be transmitted is the first step in building a Service Broker application

You create SQL Server messages by using the following syntax:

CREATE MESSAGE TYPE [ AUTHORIZATION UserName ]

[ VALIDATION = {

NONE | EMPTY | WELL_FORMED_XML |

VALID_XML WITH SCHEMA COLLECTION XMLSchemaCollectionName

} ]

You can alter message types by using the intuitive ALTER MESSAGE TYPEsyntax Before you

create the first message type, you need to create a Windows user on the local server and

associate a SQL Server login with it, giving it db_ownerpermissions in both

AdventureWorks2008andXCatMgmt You need to specify this user in the AUTHORIZATION

clause of any object you create that includes this clause In the examples in this chapter,

this is exemplified as SSBTestUserName

Messages can be validated based on the following options:

NONE—Do no validation; any message content is acceptable

EMPTY—Transmitted messages must be empty

WELL_FORMED_XML—Transmitted messages must be any well-formed XML

VALID_XML WITH SCHEMA COLLECTION—Transmitted messages must be valid XML

cor-responding to any schema in the XML schema collection specified in

XMLSchemaCollectionName.

It is highly recommended that applications use either WELL_FORMED_XMLorVALID_XML

WITH SCHEMA COLLECTION You don’t want just any old message structure coming across

the pipe because your application will almost certainly be looking for specific values in a

specific location XML is appropriate because it is the ubiquitous standard today Note that

the XML content of messages is actually stored as varbinary(MAX) (XML schema

collec-tions are covered in the section “Using XML Schema Colleccollec-tions” in Chapter 47, “Using

XML in SQL Server 2008.”)

Now you should go ahead and create your two message types, both of which should be set

toVALID_XML The first deals with catalog entries and/or changes (that is, updates and

deletions), and the second is a generic message type you use for all acknowledgments

Listing 49.2 shows the schemas for these message types, along with the necessary schema

collection and message type creation syntax

LISTING 49.2 DDL for Creating the Sample Message Types and Their Associated XML

Schema Collections

Note:

Execute the T-SQL below, and then change the USE statement

to ‘USE AdventureWorks2008’ and execute it again.

Trang 4

USE XCatMgmt

GO

CREATE XML SCHEMA COLLECTION CatalogChangeSchema

AS

‘<?xml version=”1.0”?>

<xs:schema

targetNamespace=”urn:www-samspublishing-com:examples:ssb:catalogchange”

elementFormDefault=”qualified”

xmlns=”urn:www-samspublishing-com:examples:ssb:catalogchange”

xmlns:xs=”http://www.w3.org/2001/XMLSchema”>

<xs:element name=”CatalogChangeMessage”>

<xs:complexType>

<xs:sequence maxOccurs=”unbounded”>

<xs:element name=”CatalogChange” type=”CatalogChangeType”/>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name=”CatalogChangeType”>

<xs:sequence>

<xs:element name=”Summary” type=”xs:string”/>

<xs:element name=”Features” type=”xs:string” minOccurs=”0”/>

<xs:element name=”Specifications” type=”xs:string” minOccurs=”0”/>

</xs:sequence>

<xs:attribute name=”SourceProductId” type=”xs:integer” use=”required”/>

<xs:attribute name=”ManufacturerId” type=”xs:integer” use=”required”/>

<xs:attribute name=”ChangeType”>

<xs:simpleType>

<xs:restriction base=”xs:integer”>

<xs:enumeration id=”Insert” value=”1”/>

<xs:enumeration id=”Update” value=”2”/>

<xs:enumeration id=”Delete” value=”3”/>

</xs:restriction>

</xs:simpleType>

</xs:attribute>

<xs:attribute name=”Price” type=”xs:decimal”/>

<xs:attribute name=”Name” type=”xs:string”/>

</xs:complexType>

</xs:schema>’

GO

CREATE MESSAGE TYPE

[//samspublishing.com/SS2008/SSB/MessageTypes/CatalogChangeMessage]

AUTHORIZATION [SSBTestUserName]

VALIDATION = VALID_XML

WITH SCHEMA COLLECTION CatalogChangeSchema

Trang 5

GO

CREATE XML SCHEMA COLLECTION GenericAcknowledgementSchema

AS

‘<?xml version=”1.0” encoding=”utf-8” ?>

<xs:schema

targetNamespace=”urn:www-samspublishing-com:examples:ssb:genericack”

elementFormDefault=”qualified”

xmlns=”urn:www-samspublishing-com:examples:ssb:genericack”

xmlns:xs=”http://www.w3.org/2001/XMLSchema”>

<xs:simpleType name=”MsgTypeType”>

<xs:restriction base=”xs:integer”>

<xs:enumeration id=”SuccessMsg” value=”0”/>

<xs:enumeration id=”FailureMsg” value=”1”/>

<xs:enumeration id=”WarningMsg” value=”2”/>

</xs:restriction>

</xs:simpleType>

<xs:element name=”Ack”>

<xs:complexType>

<xs:sequence>

<xs:element name=”ResultMessage”>

<xs:complexType mixed=”true”>

<xs:attribute name=”ContentId”

type=”xs:integer”

use=”optional”/>

<xs:attribute name=”MsgType”

type=”MsgTypeType”/>

</xs:complexType>

</xs:element>

</xs:sequence>

<xs:attribute name=”ResultCode”>

<xs:simpleType>

<xs:restriction base=”xs:integer”>

<xs:enumeration id=”Success” value=”1”/>

<xs:enumeration id=”Failure” value=”0”/>

</xs:restriction>

</xs:simpleType>

</xs:attribute>

</xs:complexType>

</xs:element>

</xs:schema>’

GO

CREATE MESSAGE TYPE

Trang 6

[//samspublishing.com/SS2008/SSB/MessageTypes/GenericAck]

AUTHORIZATION [SSBTestUserName]

VALIDATION = VALID_XML

WITH SCHEMA COLLECTION GenericAcknowledgementSchema

Note that the message types and schema collections should be created (as the Listing 49.2

comment indicates) in both participating databases, AdventureWorks2008andXCatMgmt.

The reason is that when you create the XML messages, you might want to temporarily

store them as local typed XML variables to ensure that they are validated before being

sent However, it is only necessary to create the schema collections on the database where

the message will be received because the receiving instance of Service Broker performs the

validation

In theMESSAGE TYPEDDL, you should use this standard naming convention for Service

Broker objects://DomainName/Path/ObjectType/ObjectName This convention will help

you identify your objects later (Don’t worry if the name is long; you can use Object

Explorer’s drag-and-drop feature to drag the name into your scripts.) If you’re curious, you

can view the newly created objects in Object Explorer by selecting theService Broker

node and then expanding theMessage Typesnode You can find the XML schema

collec-tions by selecting theProgrammabilitynode and then selecting theTypesnode and

expanding theXML Schema Collectionsnode

Note that there are several built-in message types that any queue can receive from Service

Broker Service programs should be built to handle these as well as the specific message

types defined in their contracts You can view them all in the Object Brower (they all begin

with http://schemas.microsoft.com/SQL/ServiceBroker/) When receiving messages from a

queue, you should filter them based on themessage_type_namecolumn of the queue to be

sure you handle each one correctly You can expect to see these types in your queues:

Error—This type is enqueued by Service Broker whenever an error is encountered

Alternatively, a user program can choose to create these types

EndDialog—This type is enqueued by Service Broker when a conversation ends in

response to calls toEND CONVERSATION(as explained later in this chapter)

Service programs can also send messages of the built-in type DialogTimer Service Broker

delivers these messages to the specified queue when a specific time period has elapsed To

tell Service Broker to send a DialogTimermessage to the queue associated with a service

after 5 minutes has elapsed, for example, you execute the following T-SQL during a

conversation in the service program:

BEGIN CONVERSATION TIMER (@ConversationHandle) TIMEOUT = 600

In this code, you replace @ConversationHandlewith the unique identifier assigned to your

conversation (as explained later in this chapter)

Now that all your message types are in place and you know which built-in messages to

expect, you can create the contract that defines the message flow in this system

Trang 7

Setting Up Contracts for Communication

You use contracts to specify which messages can flow from which endpoints to which

queues Two new T-SQL keywords come into play here:

INITIATOR—This service begins a messaging conversion

TARGET—This service engages in (or accepts) conversions with an initiator

As described earlier, the sample system is initiated by a stored procedure in

AdventureWorks2008that sends a message of type CatalogChangeMessageto a queue in

XCatMgmt Every CatalogChangeMessageis thus sent by a conversation initiator

The catalog management service that receives these messages sends an acknowledgment

reply message of type GeneralAckwhen it completes the requested change GeneralAck

messages in this case are thus sent by the target of the original initiated message

To create the contract that represents this message flow, you need to execute the following

code in both databases:

Note: Change SSBTestUserName to a user on your system,

and run this code on both AdventureWorks2008 and XCatMgmt

CREATE CONTRACT

[//samspublishing.com/SS2008/SSB/Contracts/BasicCatalogChangeContract]

AUTHORIZATION [SSBTestUserName]

(

[//samspublishing.com/SS2008/SSB/MessageTypes/CatalogChangeMessage]

SENT BY INITIATOR,

[//samspublishing.com/SS2008/SSB/MessageTypes/GenericAck]

SENT BY TARGET

)

This code for creating contracts also allows for message types to be sent by either the

initiator or the target, in which case, you need to specify SENT BY ANY A service can also

be bound to more than one contract Note that there is also a built-in contract called

DEFAULT(as well as a message type of DEFAULT) that you use during conversations that do

not specify a contract

Contracts cannot be altered because only DROP CONTRACTexists

Now that your contract and message types are ready, the next step is to create the queues

needed to store the messages

Creating Queues for Message Storage

Queues represent a layer of communication indirection between services, allowing them

to send and receive messages independently of each other A queue is a first-class database

object, internally implemented as a table that has some unique behaviors

Trang 8

NOTE

You can select values from any queue by using standard syntax, such as SELECT *

FROM QueueName WITH (NOLOCK) This has no effect on the data in the queue, nor

does it imply a message receive operation It does, however, cause blocking on the

internal queue table, so you should always use the NOLOCKhint Data Manipulation

Language (DML) statements on queues are not permitted

The following is the syntax for creating a queue:

CREATE QUEUE DatabaseName.SchemaName.QueueName

[ WITH

[ STATUS = { ON | OFF } [ , ] ]

[ RETENTION = { ON | OFF } [ , ] ]

[ ACTIVATION (

[ STATUS = { ON | OFF }, ]

PROCEDURE_NAME = SPName,

MAX_QUEUE_READERS = Number,

EXECUTE AS { SELF | ‘UserName’ | OWNER }

) ]

]

[ ON { filegroup | [ DEFAULT ] } ]

This syntax contains the following options:

STATUS—This option turns the queue on or off, meaning that it may or may not be

used (This capability is useful with ALTER QUEUEwhen a queue must be temporarily

put offline.) It defaults to ON

RETENTION—This option turns message retention on or off during active conversations

that use the queue It defaults toOFF You might need to turn this feature on at some

point if you need to see messages that have already been processed The reason is that

the normal message receive operation implicitly deletes a message when the

transac-tion that surrounds it commits WhenRETENTIONis set toON, the value in the status

column for the queue is changed to1after a receive instead of a deletion In addition,

sent messages are copied to the sender’s queue (duplicated) and given astatusvalue

of3, to fully audit the message flow in both directions.

ACTIVATION—This clause is used to specify the following options regarding the

inter-nally activated stored procedure (described earlier):

STATUS—This option is used to turn activation on or off (You may want to

temporarily turn off activation when updating a procedure.) It defaults toON.

PROCEDURE_NAME—This option specifies the name of the activated procedure

Trang 9

MAX_QUEUE_READERS—This option supplies an integer that indicates to Service

Broker the maximum number of instances of the activated procedure to create

This setting hints at the fact that Service Broker uses multithreading to

instan-tiate additional queue readers when unread messages in the queue build up

faster than the existing instances can process them This is a great boon to

developers because they no longer have to develop and maintain the

multi-threaded code to perform this task To do this, Service Broker internally creates

queue monitors that keep an eye on the number of unread messages in the

queue Keep this number the same as the number of processor cores you have

in your system

EXECUTE AS—This option specifies the name of the user under which the

initi-ated procedure runs

You need two queues for the application so far: one used by each service The T-SQL in

Listing 49.3 creates them

LISTING 49.3 T-SQL for Creating Queues and Their Activated Stored Procedures

USE XCatMgmt

GO

CREATE PROC Publication.CatalogChangeQueueReader

AS

GO

CREATE QUEUE Publication.CatalogChangeQueue

WITH

STATUS = ON,

ACTIVATION

(

STATUS = ON,

PROCEDURE_NAME = Publication.CatalogChangeQueueReader,

MAX_QUEUE_READERS = 10,

EXECUTE AS ‘SSBTestUserName’

)

GO

USE AdventureWorks2008

GO

CREATE PROC Production.CatalogChangeAckQueueReader

AS

GO

CREATE QUEUE Production.CatalogChangeAckQueue

WITH

STATUS = ON,

ACTIVATION

(

STATUS = ON,

PROCEDURE_NAME = Production.CatalogChangeAckQueueReader,

Trang 10

MAX_QUEUE_READERS = 10,

EXECUTE AS ‘SSBTestUserName’

)

The code in Listing 49.3 declares an empty stored procedure for each queue You can fill

this shell after you define the services

Defining Services to Send and Receive Messages

Services represent the endpoints in Service Broker applications You can think of them as

the glue that binds contracts with queues This binding ensures that the typed messages

specified in the contract end up in the appropriate queues

Here is the DDL syntax for creating services:

CREATE SERVICE ServiceName

[AUTHORIZATION OwnerName]

ON QUEUE [SchemaName.]QueueName

[( ContractName | [ DEFAULT ] [ , n ] )] [;]

For this example, you need to create two services: the initiator in AdventureWorks2008and

the target in XCatMgmt

This is the initiator in AdventureWorks2008:

USE AdventureWorks2008

GO

CREATE SERVICE

[//samspublishing.com/SS2008/SSB/Services/CatalogChangeInitiatorService]

AUTHORIZATION [SSBTestUserName]

ON QUEUE

Production.CatalogChangeAckQueue

([//samspublishing.com/SS2008/SSB/Contracts/BasicCatalogChangeContract])

And this is the target in XCatMgmt:

USE XCatMgmt

GO

CREATE SERVICE

[//samspublishing.com/SS2008/SSB/Services/CatalogMaintenanceService]

AUTHORIZATION [SSBTestUserName]

ON QUEUE

Publication.CatalogChangeQueue

([//samspublishing.com/SS2008/SSB/Contracts/BasicCatalogChangeContract])

As you can see, creating services is simple Now that all the plumbing is in place, you can

begin the dialog between the services

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN