본문 바로가기

MSSQL

SQL Server 2005 개발자 가이드[5/13]


SQL Server Service Broker

서비스지향기술구조(SOA)는 대규모 분산 어플리케이션을 설계하기 위해 중요한 개념으로 자리를 확고하고 있습니다. SOA의 중심부에는 서비스간에 통신을 위한 신뢰할 수 있는 메시지 기반 매커니즘이 위치하고 있습니다. SQL Server 2005에서 서비스 지향 데이터베이 스 솔루션을 개발하기 위한 메시지 기반 플랫폼의 역할을 하는 Service Broker에 대해서 소개합니다. 데이터베이스 어플리케이션 간의 메시지교환을 위한 Service Broker의 기능을 살펴보기에 앞서, SOA의 전체적인 개념에 대해서 먼저 알아두어야 합니다.

SOA 란?
최종 사용자에 대한 지연현상을 감소시키거나 확장성을 증대하기 위해서, 대부분의 대용량 시스템은 전통적인 통신 접근방법과 다른 방식의 통신 접근방법을 필요로 하고 있습니다. SOA는 대용량 시스템의 이러한 요구사항을 충족시켜 줄 수 있는 통신 접근방법의 역할을 합니다.

정의
SOA는 소프트웨어 서비스간에 느슨하게 연결된 통신을 보장하는 기술구조의 유형입니다. 서비스는 비즈니스 업무에 대한 소프트웨어적인 구현으로, 통신을 위한 인터페이스와 계약을 제공합니다. 느슨하게 연결된 통신이란 클라이언트와 서비스가 서로에게 비교적 낮은 수준의 의존성을 갖는다는 의미입니다. 예를 들어, 서비스내부에 존재하는 로직은 클라이언트에 영향을 주지 않고 수정이 가능하며, 클라이언트도 서비스내부에 존재하는 로직과 상관없이 수정될 수 있습니다.

웹 서비스 사례
소프트웨어는 웹 서비스를 사용하여 인터넷을 통해 통신이 가능합니다. 웹 서비스는 클라이언트가 서비스 공급자가 노출시킨 인터페이스를 통해 서비스를 호출하기 때문에, SOA의 한 사례가 될 수 있습니다. 클라이언트에게 노출된 인터페이스가 웹 서비스 내부의 로직을 호출하며, 서비스 공급자는 클라이언트에 영향을 주지 않고, 내부 로직을 수정할 수 있습니다. 웹 서비스는 XML과 SOAP을 사용하여 서로간에 통신을 수행합니다.

메시징 사례
서비스는 Windows NT 4.0 이후에서 제공되는 기능인, 메시지 큐와 같은, 메시징 기술을 사용하여 통신하게 됩니다. 메시징 기술은 서비스 소비자와 서비스 공급자간의 비동기 통신을 가능하게 합니다.


SOA 용어
다음 표에는 SOA 관련 용어에 대한 설명이 나타나 있습니다.
항목 설명
서비스 특정 작업 또는 관련된 작업의 집합으로 구현된 소프트웨어
서비스공급자 계약에 의해 정의된 서비스 규약을 구현한 소프트웨어. 서비스 공급자는 서비스 소비자로서도 동작할 수 있습니다.
서비스소비자 서비스 공급자를 호출하는 소프트웨어. 서비스 소비자는 또한 서비스 공급자로서도 동작할 수 있습니다.
메시지 서비스간에 통신의 단위 인스턴스. 서비스 공급자와 서비스 소비자는 메시지를 사용하여 통신을 수행합니다. 메시지의 양식은 SOA의 구현에 따라 다양한 구조를 가질 수 있습니다. 하지만, 메시지 양식은 플랫폼에 독립적이기 때문에, 잠재 서비스 소비자에게 제한없이 제공될 수 있습니다.
계약 두 개의 서비스간에 체결된 각 서비스에서 받아들일 수 있는 메시지에 대한 규약. 계약은 외부 개발자가 프로그래밍 관점에서 서비스가 제공하는 기능을 이해하도록 도와줍니다.
대화(conversation) 관련된 메시지의 교환. 때로 다수의 메시지가 하나의 작업을 완료하기 위해 필요하기도 합니다. SOA에서는 대화안에 메시지를 연결할 수 있는 매커니즘을 제공해야 합니다.
메시지가 처리될 때까지 메시지가 대기하는 저장소. 비동기 통신을 처리하기 위해, 서비스가 해당 메시지를 처리할 때까지, 큐에는 대기중인 메시지가 임시로 저장됩니다.

Service Broker의 기능
SQL Server 2005 Service Broker는 데이터베이스 어플리케이션에 메시징 기능을 제공하는 SOA의 구현의 역할을 수행합니다. Service Broker를 통해, SOA 기반 솔루션에서 제공하는, 다음과 같은, 강력한 기능을 사용할 수 있습니다.

항목 설명
메시지를 한번에 순서에 따라 수신 Service Broker는 보내진 순서에 따라 순서대로 한 번에 하나씩 메시지를 수신하기 위해 식별자를 사용합니다. 서비스 공급자와 서비스 소비자의 역할을 하는, 두 개의 Service Broker 엔드포인트간에 지속적인 대화의 일부로 처리됩니다. 서비스 어플리케이션에서는 대화 식별자를 사용하여 별도의 코드를 작성하지 않고서도 정확하게 순서에 따라 하나씩 메시지를 처리할 수 있습니다. 대화 식별자를 통해, 메시지 처리를 위한 정확성을 보장하기 위해서 필요한 코드 작성 노력을 절감할 수 있습니다.
대화을 사용하여 관련 메시지를 조정 관련된 메시지를 처리할 때 일관성을 보장하기 위해서, 한 번에 하나의 서비스 프로그램 인스턴스가 대화에 대한 메시지를 큐에서 가져와서 처리하게 할 수 있습니다. 물론, 다른 서비스 프로그램 인스턴스가 해당 대화와 관련없는 메시지를 큐에서 가져올 수는 있습니다.
비동기 전달 Service Broker는 클라이언트 어플리케이션에서 메시지를 보낸 다음, 서비스 공급자가 결과값을 반환할 때까지 기다리지 않기 위해서, 비동기식 메시지 기반 접근방법을 사용하여 통신합니다. 사실, 서비스 공급자는 클라이언트가 메시지를 보내는 시점에 반드시 운영중일 필요도 없습니다. 클라이언트에서 보내진 메시지는 서비스 공급자가 해당 메시지를 처리할 수 있을 때까지, 큐에 저장되어 대기하게 됩니다.
스케줄링과 처리절차의 유연성 Service Broker는 현재 작업부하에 따라 메시지를 처리하기 편리한 시점에 메시지를 큐에서 가져와서 서비스 처리절차를 수행합니다. 서버가 너무 과부하 상태인 경우에는 야간시간을 통해 메시지를 배치 처리하게 되어, 주간 업무시간대의 서버의 작업부하를 절감할 수 있습니다. 클라이언트 어플리케이션에서는 메시지를 비동식으로 보내기 때문에, 이러한 변경사항에서 대해서 인식하지 못합니다.
자동 서비스 프로그램 활성화 Service Broker는 큐에 메시지가 도착했을 때 자동으로 서비스 프로그램을 시작하도록 설정할 수 있습니다. 만약, 하나의 서비스 프로그램 인스턴스로 현재 수신된 메시지의 양을 처리할 수 없다면, 구성된 최대값까지, 서비스 프로그램 인스턴스를 추가로 실행합니다. 메시지 처리율이 낮아지면, Service Broker는 필요 없는 서비스 프로그램을 종료시킵니다. 시스템이 재시작되면, Service Broker는 필요한 만큼의 서비스 프로그램만 실행합니다.
데이터베이스와 통합 Service Broker 는 메시지, 큐, 기타 관련 항목을 모두 데이터 베이스로 통합하는 역할을 하기 때문에, 트랜잭션 메시징 기능을 제공합니다. 서비스 프로그램(메시지에 대한 수신, 처리, 클라 이언트에 대한 응답을 수행)의 각 반복 작업을 단일 데이터베이스 트랜잭션으로 처리할 수 있습니다. 트랜잭션이 실패하면, 해당 메시지는 추후에 서비스 프로그램이 다시 메시지를 처리할 수 있도록 큐에 재저장됩니다. 관리자 측면에서도, Service Broker 와 데이터베이스가 통합됨으로써 많은 관리작업의 부담을 줄일 수 있습니다. 관리자는 별도의 구성작업없이 표준 SQL Server 데이터베이스 백업전략의 일부로 Service Broker 컴포넌트를 포함시켜, 표준 백업절차를 보조하도록 설정할 수 있습니다.
보안이 보장되는 통신 Service Broker는 네트워크 연결간에 발생하는 대화를 암호화 하기 위해 디지털 인증서를 사용합니다. 대화에 참석하는 대상에서는 Windows 사용자 신임장이나 디지털 인증를 사용하여 인증을 받을 수 있습니다.

Service Broker의 시스템 기술구조
Service Broker 어플리케이션을 개발하기 전에, 먼저 Service Broker 기술구조에 포함된 다섯 가지 SQL Server 개체에 대해서 알아두어야 합니다.
개체 설명
메시지유형 서비스 소비자는 서비스 공급자에게 메시지를 송신합니다. 서비스 소비자와 서비스 공급자는 각각 서로 교환할 메시지의 유형과 메시지에 대한 유효성 검사 방법을 합의해야 합니다. 소비자 데이터베이스와 공급자 데이터 베이스에 식별가능한 메시지 유형을 생성해야 합니다.
계약 Service Broker에서는 좀 더 포괄적인 SOA 계약을 구현하기 위해 contract 개체를 제공합니다. Contract 개체는 작업을 완료하기 위해 포함되어야 하는 메시지 유형과 각 메시지 유형을 송신하는 주체에 대해 정의합니다. Contract 개체는 다음과 같이 메시지 유형을 송신하는 주체를 제한합니다.

    Initiator Only : 시작자(initiator) 엔드포인트만 지정된 메시지 유형을
       보낼 수 있습니다. 시작자 엔드포인트란 대화를 시작하는 엔드포인트를
       의미합니다.
    Target Only : 대상 엔드포인트에서만 지정된 메시지 유형을 보낼 수
       있습니다. 대상 엔드포인트란 시작자 엔드포인트로 부터 전송된 메시지
       를 수신하는 엔드포인트를 의미합니다.
    Any Both : 각 엔드포인트에서 지정된 메시지 유형을 보낼 수 있습니다.

각 contract 개체를 소비자 데이터베이스와 공급자 데이터베이스에 모두 생성해야 합니다.
Service Broker 는 서비스에 메시지를 송신하고, 서비스는 해당 메시지를 큐에 저장합니다. 서비스 소비자는 서비스 공급자 서버가 가용한 상태가 아닌 경우, 해당 메시지를 로컬 큐에 저장합니다. Service Broker는 메시지를 재전송하고, 해당 메시지가 서비스 공급자의 큐에 정상적으로 도착한 경우, 해당 메시지를 로컬 큐에서 삭제합니다. 소비자와 공급자가 동일한 SQL Server 인스턴스에 설치되어 있는 경우에는, 큐가 하나만 사용됩니다.Service Broker는 queue 개체를 메시지를 개별 행으로 보유하고 있는 테이블로 구현합니다. 각 행에는 대화 식별자, 계약 정보 등과 같은 기타 정보도 포함됩니다. Service Broker는 메시지를 수작업으로 조회하는 경우, 큐로부터 메시지를 제거합니다. 또한 큐는 메시지가 도착한 경우 자동으로 해당 메시지를 처리하기 위한 서비스 프로그램을 실행합니다. Service Broker는 큐의 구성정보에 따라, 처리되어야 하는 메시지의 요청량이 많아지게 되는 경우, 해당 메시지를 처리하기 위해서, 하나 이상의 서비스 프로그램 인스턴스를 생성할 수 있습니다.
서비스 프로그램 서비스 프로그램은 메시지를 처리하고, 서비스의 실제 처리 로직을 제공합니다. Service Broker는 메시지가 도착했을 때, 자동으로 서비스 프로그램을 활성화시킵니다. 또는 일정을 설정하여 특정 시점에 서비스 프로그램을 실행할 수도 있고, 수작업으로 실행시킬 수도 있습니다. 서비스 프로그램은 작업을 완료하기 위해 대화를 시작한 시작자 엔드포인트에 응답메시지를 보내주어야 합니다. 이러한 응답 메시지도 초기 시작자 엔드포인트에서 정확한 응답메시지를 수신할 수 있도록 하기 위해서 동일한 대화의 일부로 처리됩니다.
서비스 service 개체는 서비스를 제공하는 접근 가능한 엔드포인트로 표현 됩니다. Service 개체는 해당 서비스에 대한 메시지를 저장할 큐의 명칭을 정의하고, 해당 Service 개체가 어떤 계약에 대해서 공급자의 역할을 수행하는지를 정의합니다. 서비스에 계약이 지정되지 않으면, 서비스는 대화를 시작할 수만 있고, 서비스의 공급자가 될 수는 없습니다.
Service Broker 대화 기술구조
Service Broker 통신은 메시지를 교환하기 위해 대화를 사용합니다. 대화는 신뢰할 수 있는 메시지를 순서에 따라 보내기 위한 구조로 되어 있습니다. Service Broker 기반 어플리케이션을 개발하기 위해서는, Service Broker의 대화 기술구조에 대해서 알고 있어야 합니다.

 


Service Broker의 대화처리절차
Service Broker 어플리케이션에서는 단순하게 서비스 공급자에게 개별 메시지를 보내는 기능만 있는 것이 아니라, 부가적인 기능이 좀 더 포함되어 있습니다. 서비스 소비자는 작업이 완료되었을 때, 응답 메시지를 받기를 희망합니다. 하나의 작업을 완료하기 위해 여러 번의 대화가 이루어 질 수 있고, 수 시간에서 수일까지 시간이 소요될 수 있습니다. 

 
Service Broker 보안 기술구조
웹 서비스에서 네트워크 연결을 통해 대화를 수행하는 경우, 교환되는 메시지에 대한 보안이 보장되어야 합니다. Service Broker에서는 전송 보안과 대화 보안을 모두 지원합니다.

전송보안
Service Broker는 대화를 하기 위해 계약된 두 개의 서비스 간에 보안이 보장되고, 인증된 연결을 설정하기 위해 전송 보안을 사용합니다. 서비스는 원격서버의 HTTP 엔드포인트에 메시지를 송신하기 위해 다음과 같은 인증 옵션을 사용할 수 있습니다.

    None - 서비스에 익명 접근을 허용합니다.
    Enabled - 서비스에 익명 접근을 허용하며, 호출하는 서비스에서 제공하거나, 호출하는 서비스
       가 요청하는 경우에만 인증을 사용합니다.
    Required - 인증을 필수로 사용합니다.

인증
사용되는 인증의 유형은 호출자 어플리케이션의 master 데이터베이스에 존재하는 dbo 사용자가 디지털 인증서를 보유하고 있는지 여부에 따라 결정됩니다. 디지털 인증서가 존재하는 경우, 인증서 기반 인증이 사용됩니다. 디지털 인증서가 없는 경우, Windows 인증이 사용됩니다.

인증서 기반 인증을 사용하기 위해서는, 각 서비스의 관리자별로 master 데이터베이스내에 dbo 사용자에 대한 디지털 인증서를 생성한 다음, 해당 인증서에 대한 공개키를 내보내기하고, 원격 서비스 관리자에게 해당 공개키를 전달합니다. 각 관리자는 원격 서비스내에 dbo 사용자를 대표하기 위해서, master 데이터베이스에 사용자를 생성한 다음, 새로 생성한 사용자에 원격 관리자에 의해 제공된 공개키를 연결해야 합니다.

Windows 인증을 사용하기 위해서는, 각 서비스의 관리자는 원격 서비스의 서비스 계정으로 사용할 Windows 로그온을 위한 사용자를 master 데이터베이스에 생성해야 합니다.

대화(Dialog) 보안
Service Broker 는 원격 서비스간의 메시지를 암호화하고, 원격 사용자에 대한 인증절차를 처리하기 위해 대화 보안을 사용합니다. 대화 보안은 높은수준의(full) 대화 보안과 익명 대화 보안으로 구현될 수 있습니다.

높은 수준의 대화 보안의 경우, 대화를 시작하는 서비스를 호스팅하는 데이터베이스와 호출된 서비스를 호스팅하고 있는 데이터베이스 양쪽 모두에 두 가지 사용자를 포함하고 있어야 합니다. 하나는 원격 서비스에 메시지를 보내는 로컬 사용자이고, 또 하나는 원격 서비스를 호스팅하고 있는 원격 데이터베이스내의 사용자입니다. 대화에 포함되는 각 서비스에는 원격 서비스와 원격 데이터베이스 사용자에 대한 로컬 사용자 계정을 매핑하는 원격 서비스 바인딩 정보가 포함되어야 합니다. 디지털 인증서는 메시지를 수신자의 공개키로 암호화한 다음, 그에 상응하는 개인키로 복호화할 수 있도록, 반드시 각 사용자와 연결되어 있어야 합니다.

익명 대화 보안은 대부분 전체 대화 보안과 동일한 방식으로 동작하지만, 대상 서비스에서 원격 사용자에 대한 접근을 명시적으로 허용할 필요가 없다는 차이가 있습니다. 익명 대화 보안을 사용하면, 대상 서비스는 guest 계정으로 접근을 허용하며, 세션키를 생성하여, 서비스간에 교환되는 메시지를 암호화하기 위해 사용합니다.
데이터베이스에서 Service Broker 활성화
Service Broker 서비스는 데이터베이스가 생성될 때, 기본값으로 활성화되지 않습니다. TSQL 문장을 사용하여, Service Broker 서비스가 활성화되어 있는지 여부를 확인하고, 활성화/비활성화 시킬 수 있습니다. Service Broker가 비활성화되어 있는 경우, 다시 활성화될 때까지 모든 메시지는 전송 큐에 저장되게 됩니다.

Service Broker 상태 체크
데이터베이스의 Service Broker의 상태를 확인하기 위해서는, 다음 예제와 같이, sys.databases 카탈로그 뷰에서 is_broker_enabled 컬럼을 조회하면 됩니다.
SELECT is_broker_enabled
FROM sys.databases
WHERE database_id = db_id( )

Service Broker 활성화
데이터베이스의 Service Broker를 활성화/비활성화 시키기 위해서는, 다음 예제와 같이, ALTER DATABASE T-SQL 명령을 사용합니다.
ALTER DATABASE AdventureWorks
SET ENABLE_BROKER

Service Broker 구현
계약 생성
Service Broker 어플리케이션을 개발하기 위해서 데이터베이스에 생성해야 하는 개체는 계약과 메시지 유형이 있습니다. 계약은 서비스 간에 교환되는 메시지 유형의 목록을 정의합니다. 계약을 생성하기 위해서는, 다음과 같은 단계의 작업을 수행해야 합니다.

1 단계. 메시지 유형 생성
메시지 유형은 서비스간에 전송되는 데이터의 유형을 정의합니다. VALIDATION 절에는 메시지에 포함될 데이터의 유형을 지정합니다. 메시지에 포함된 데이터의 유형에는 다음과 같은 항목 중 하나를 선택하여 지정합니다.

    NONE - 메시지에 대한 유효성검사를 수행하지 않습니다.
    EMPTY - 메시지에 데이터를 포함하지 않습니다.
    WELL_FORMED_XML - 메시지에 잘 구성된 XML 문자열만 포함되도록 설정합니다.
       XML이 잘 구성된상태가 아니라면, Service Broker에서 오류를 발생시킵니다.
    VALID_XML - 지정된 XML 스키마 컬렉션에 포함된 스키마를 기준으로 검증된 XML 데이터만
       메시지에 포함됩니다.

AUTHORIZATION 절에 메시지 유형의 소유자로 사용할, 특정 데이터베이스 사용자나 역할을 설정할 수 있습니다.

알림
Service Broker 어플리케이션에 메시지 적어도 하나의 메시지 유형은 반드시 포함되어야 하며, 대화에 포함될 각 데이터베이스별로 메시지 유형을 재생성해야 합니다.

다음과 같은 구문으로 메시지 유형을 생성할 수 있습니다.
CREATE MESSAGE TYPE message_type_name
[AUTHORIZATION owner_name]
[VALIDATION =
   {NONE | EMPTY | WELL_FORMED_XML |
   VALID_XML WITH SCHEMA COLLECTION schema_collection_name}]

[따라하기] 메시지 유형 만들기
CREATE MESSAGE TYPE
[//Adventure-Works.com/Expenses/ExpenseClaim]
VALIDATION = WELL_FORMED_XML
CREATE MESSAGE TYPE
[//Adventure-Works.com/Expenses/ClaimResponse]
VALIDATION = VALID_XML WITH SCHEMA COLLECTION awschemas

2. 계약 생성
계약에는 대화에서 사용하게 될 메시지 유형을 정의해야 하고, 메시지 유형이 전송되는 방향(direction)을 정의해야 합니다.

사용할 메시지 유형을 생성한 다음, 다음과 같은 구문으로, 계약을 생성할 수 있습니다.
CREATE CONTRACT contract_name
[ AUTHORIZATION owner_name ]
( message_type_name SENT BY { INITIATOR | TARGET | ANY }
[ ,...n] )

위의 구문에서 message_type_name 는 사전에 정의된 메시지 유형 이름을 지정합니다.
SENT BY는 대화에서 메시지 유형을 전달할 수 있는 방향을 지정합니다. owner_name 에는 계약의 소유자로 설정할 데이터베이스 사용자나 역할을 지정합니다.

[따라하기] 계약 생성
CREATE CONTRACT
[//Adventure-Works.com/Expenses/ExpenseSubmission]
( [//Adventure-Works.com/Expenses/ExpenseClaim]
SENT BY INITIATOR,
[//Adventure-Works.com/Expenses/ClaimResponse]
SENT BY TARGET
앞의 예제에서는, 시작자(intiator) 서비스에서만 ExpenseClaim 메시지를 보낼 수 있으며, 대상 서비스에서만 ClaimResponse 메시지를 보낼 수 있습니다.

큐 생성
큐는 서비스 프로그램이 메시지를 처리할 수 있는 상태까지, Service Broker가 메시지를 저장할 장소를 정의합니다. 큐를 생성하기 위해서는 다음과 같은 작업절차를 수행해야 합니다.

1. 큐의 이름을 생성합니다.
2. 큐의 가용량을 정의합니다.
3. 활성화 조건 매개변수를 지정합니다.

큐를 생성하기 위한 구문은 다음과 같습니다.
CREATE QUEUE queue_name
[ WITH
[ STATUS = { ON | OFF } [ , ] ]
[ RETENTION = { ON | OFF } [ , ] ]
[ ACTIVATION (
[ STATUS = { ON | OFF } , ] PROCEDURE_NAME = stored_procedure_name ,
MAX_QUEUE_READERS = max_readers ,
EXECUTE AS { SELF ‘| user_name’| OWNER } ) ] ]
[ ON { filegroup | [ DEFAULT ] } ]

서비스 생성
서비스는 서비스 소비자와 서비스 공급자를 연결하는 역할을 합니다. 서비스에는 대화가 시작된 다음, 대화가 종료될 때까지의 범위가 포함됩니다.

서비스를 생성하기 위해서는 다음과 같은 작업을 수행해야 합니다.

    서비스명을 생성합니다.
    서비스 소비자가 보낸 메시지를 저장하기 위한 큐를 지정합니다.
    서비스 공급자의 계약 목록을 지정합니다.
    대화가 진행되는 동안 메시지를 계속해서 유지할 것인지 여부를 지정합니다.

다음 표에는 CREATE SERVICE 문장에 포함되는 각 구문에 대한 설명이 나타나 있습니다.
매개변수 Description
service_name 서비스를 식별하기 위한 서비스명
AUTHORIZATION 서비스의 소유자로 지정할 데이터베이스 사용자 또는 역할
ON QUEUE 메시지를 지정하기 위한 큐를 지정합니다.
contract_name 서비스 공급자가 제공하는 계약의 목록을 지정합니다. 계약이 하나도 지정되지 않으면, 서비스는 대화를 시작하는 기능만 수행합니다.

[따라하기] 서비스 생성하기-서로 다른 큐를 사용하는 두 개의 서비스
CREATE SERVICE [//Adventure-Works.com/SubmitExpense]
ON QUEUE ExpensesInitiator
( [//Adventure-Works.com/Expenses/ProcessExpense] )

CREATE SERVICE [//Adventure-Works.com/ProcessExpense]
ON QUEUE ExpensesTarget
( [//Adventure-Works.com/Expenses/ProcessExpense] )

메시지 송신
Service Broker 어플리케이션에서 수행해야 하는 가장 기본적인 작업 중 하나는 서비스 소비자로부터 서비스 공급자에게로 메시지를 보내는 것입니다. 메시지를 보내기 위해서는, 먼저 계약, 큐, 서비스와 같은, 관련 Service Broker 개체가 먼저 생성되어 있어야 합니다.

메시지를 보내기 위해서는, 다음과 같은 작업절차를 수행해야 합니다.

1. 대화를 관리하기 위한 식별자 변수 선언
메시지를 보내기 전에, 대화를 관리하기 위한 식별자 변수를 선언해야 합니다. 대화를 관리하기 위한 변수는, 다음 예제와 같이, 반드시 uniqueidentifier 데이터형을 사용해서 선언해야 합니다.
DECLARE @dialog_handle uniqueidentifier

2. 대화 시작
BEGIN DIALOG CONVERSATION 명령을 사용하여 대화를 시작할 수 있습니다.
BEGIN DIALOG CONVERSATION 명령에 대한 구문은 다음과 같습니다.
BEGIN DIALOG [CONVERSATION] dialog_handle_identifier
   FROM SERVICE service_name
   TO SERVICE‘ service_name’[ , broker_instance ]
   ON CONTRACT contract_name
   [ WITH
   [ { RELATED_CONVERSATION = conversation_handle
         | RELATED_CONVERSATION_GROUP = conversation_group_id } ]
   [ [ , ] LIFETIME = dialog_lifetime ]
   [ , ] ENCRYPTION = { ON | OFF } ] ]

다음 표에는 BEGIN DIALOG 구문에서 사용하는 매개변수 목록이 나타나 있습니다.
매개변수 설명
dialog_handle_identifier 새로 생성된 대화 식별자 핸들을 반환합니다. 새 식별자를 저장하기 위해 대화핸들변수가 사용됩니다.
FROM SERVICE 메시지를 보내는 서비스를 지정합니다. 서비스를 초기화할 때 사용할 서비스명을 지정해야 합니다. 서비스에서 지정한 큐로 대상 서비스에서 반환한, 오류나 대화종료 메시지와 같은, 모든 메시지가 수신됩니다.
TO SERVICE 대화를 시작하려고 하는 대상 서비스의 이름을 지정합니다. Service_name은 문자열 상수값이거나, 암시적으로 문자열로 형변환할 수 있는 변수로 지정해야 합니다. 또한, 대소문자를 구별하는 것에 유의해야 합니다.
broker_instance 대상 서비스가 하나 이상의 데이터베이스에서 호스팅되고 있는 경우, 대상 데이터베이스를 지정하기 위해 사용할 수 있는 유일한 식별자입니다.
ON CONTRACT 서비스에서 통신하기 위해서 사용하려는 계약명을 지정합니다.
WITH RELATED_CONVERSATION 식별자나 RELATED_CONVERSATION _GROUP 식별자를 사용하여 기존 대화에 새 대화를 연결하기 위해서 사용합니다. 또한, LIFETIME 옵션을 사용하여 대화가 오픈된 상태로 유지되는 최대지속시간을 초단위로 지정할 수 있습니다. LIFETIME 옵션이 지정되지 않으면, 양쪽 엔드포인트에서 명시적으로 대화를 종료해 주어야 합니다.
ENCRYPTION 대화에서 주고 받는 모는 메시지를 암호화할 것인지여부를 지정합니다. 기본 옵션은 서로 다른 SQL Server 인스턴스간에는 메시지를 암호화하는 것입니다. 동일한 인스턴스에 설치된 서비스 간의 대화는 암호화되지 않습니다.

[따라하기] 대화시작
BEGIN DIALOG CONVERSATION @dialog_handle
   FROM SERVICE [//Adventure-Works.com/SubmitExpense]
   TO SERVICE‘ //Adventure-Works.com/ProcessExpense’
   ON CONTRACT [//Adventure-Works.com/Expenses/ProcessExpense]
3. 메시지 송신
대화 핸들 식별자가 설정되면, SEND 명령을 사용하여 메시지를 송신하게 됩니다. SEND 명령에 대한 구문은 다음과 같습니다.
SEND ON CONVERSATION conversation_handle
MESSAGE TYPE message_type_name
[ ( message_body_expression ) ]

다음 표는 SEND 명령에서 사용하는 매개변수의 목록을 나타냅니다.
매개변수 설명
conversation_handle 대화 식별자에 대한 핸들값을 지정합니다. BEGIN DIALOG 명령 에 의해서 반환된 uniqueidentifier 데이터형 핸들값을 지정합니다. 단순히 대화의 대상 측에서 대화를 시작한 측으로 응답메시지를 회신하기 위해서라면, 대화를 시작한 측에서 보내온 메시지 내에 설정된 대화 식별자 핸들값을 지정합니다.
MESSAGE TYPE 계약에서 정의된 현재 엔드포인트에서 전송할 수 있는 메시지 유형을 지정해야 합니다. 시작자측 엔드포인트에서는 SENT BY INITIATOR, SENT BY ANY로 표시된 메시지 유형을 지정할 수 있습니다. 또한, 대상측 엔드포인트에서는, SENT BY TARGET, SENT BY ANY로 표시된 메시지 유형을 지정할 수 있습니다.
message_body_expression 송신할 메시지의 본문을 지정합니다. 메시지 본문은 적절한 메시지 유형에 일치하는 형식으로 지정되어야 합니다.

[따라하기] 메시지송신
DECLARE @msgString NVARCHAR(MAX)
SET @msgString = NCHAR(0xFEFF) + N’xml data’
;SEND ON CONVERSATION @dialog_handle
MESSAGE TYPE [//Adventure-Works.com/Expenses/ExpenseClaim]
(@msgString)

앞의 예제는 메시지가 XML 본문으로 구성되었다고 가정합니다. XML 형식 문자열에 대해서 메시지 송신 작업을 하기 위해서는, XML 데이터 앞에 바이트 순서 표시를 포함한 문자열인 지를 확인해야 합니다. NCHAR(OxFEFF) 값이 바이트 순서 표시로 사용됩니다.


SEND 문장이 배치나 저장 프로시저의 첫 문장이 아닌 경우에는, 반드시 세미콜론(;) T-SQL 종결자를 사용해야 합니다.


메시지 수신
메시지가 보내지면, 서비스 프로그램은 큐로부터 보내진 메시지를 읽어 들여, 메시지 본문에 대한 처리를 수행합니다. 서비스 프로그램이 메시지를 읽는 방법은 큐를 설정할 때 선택한 방법에 따라 결정됩니다. 물론, 공통적인 메시지 수신 절차는 변경되지 않습니다.

메시지를 수신하기 위해서는 다음과 같은 작업절차가 수행됩니다.

1 단계. 메시지 상세정보를 저장하기 위한 변수선언
메시지의 개별 컬럼을 저장하기 위한 로컬 변수를 생성해야 합니다. 작업을 위해 공통적으로 필요한 컬럼에는 conversation_handle, message_type_name, message_body 등이 있습니다.

2 단계. RECEIVE 명령 호출
RECEIVE 명령은 큐에 저장된 메시지를 처리하여, 테이블 기반 결과값과 같은 결과를 만들어 내는 작업을 수행하기 위해, 지정된 큐로부터 하나 또는 그 이상의 메시지를 가져오는 역할을 합니다. RECEIVE 명령에 별도로 TOP 매개변수를 지정하지 않으면 동일한 서비스 인스턴스 식별자에 소속된 모든 메시지를 큐에서 제거하여 가져옵니다. RECEVIE 명령이 큐에서 메시지를 제거하는 동안에는, 다른 서비스 프로그램 인스턴스가 RECEIVE 명령의 대상이 되는 메시지에 대한 작업을 수행할 수 없으며, 동일한 서비스 인스턴스 식별자가 소유한 메시지에 대한 다른 작업도 수행할 수 없습니다. RECEIVE 명령은 대화에 포함된 각 메시지의 message_sequence_order 값의 순서에 따라 메시지를 큐에서 제거합니다.

RECEIVE 명령에 대한 구문은 다음과 같습니다.
[ WAITFOR ( ]
  RECEIVE [ TOP (n) ]
      <column_specifier > [ ,...n ]
      FROM queue_name
      [ INTO table_variable ]
      [ WHERE { conversation_handle = conversation_handle
      | conversation_group_id = conversation_group_id } ]
[ ) ] [ , TIMEOUT timeout ]

다음 표는 RECEIVE 명령에서 사용할 수 매개변수 목록을 나타냅니다.
매개변수 설명
WAITFOR 메시지가 큐에 도착할 때까지 RECEIVE 명령에 대한 처리를 유보합니다. TIMEOUT 값을 밀리초 단위로 지정하면, RECEIVE 명령은 도착한 메시지가 없는 경우, 빈 결과값을 반환하기 전에 주어진 TIMEOUT 값만큼 대기합니다. TIMEOUT 값을 지정하지 않거나, -1 을 지정하면, RECEIVE 명령은 메시지가 도착할 때까지 대기하게 됩니다.
TOP 큐로부터 몇 개의 메시지를 수신할 것인지를 지정합니다. TOP 매개변수를 지정하지 않으면, 특정 서비스 인스턴스 식별자에 해당하는 모든 메시지를 수신합니다. 일반적으로, 개별 메시지 단위로 작업하기 위해, 1로 지정합니다.
column_specifier 메시지 처리 로직에 사용할 컬럼목록을 지정하기 위해 사용합니다. 완료 목록에 대해서는 SQL Server 2005 온라인 도움말을 참조하십시오.
FROM 메시지를 수신하기 위해서 체크할 큐의 이름을 지정합니다.
INTO 로컬 변수가 아닌 특정 테이블에 결과값을 지정하기 위해서 사용합니다. 동시에 다수의 메시지를 처리해야 하는 상황에서는 로컬 변수 대신 테이블을 사용하는 방법을 사용해야 합니다.
WHERE 특정 대화 핸들이나 대화 그룹 식별자에 대한 메시지만 반환할 수 있도록 제한하기 위해서 사용합니다. WHERE 절에 다른 컬럼이 사용될 수는 없습니다.

다음의 예제는 하나의 메시지를 수신하여, 해당 메시지에 포함된 세 개의 컬럼의 정보를 로컬 변수에 저장하는 방법을 나타냅니다.

[따라하기] 메시지 수신
;RECEIVE TOP(1) @conversation = conversation_handle,
    @msgType = message_type_name, @msg = message_body
FROM ExpenseQueue


RECEIVE 명령에서 메시지를 발견했는지를 체크하기 위해 @@ROWCOUNT 값을 확인해야 합니다. @@ROWCOUNT 값이 0 인 경우에는, 큐에 메시지가 하나도 저장되어 있지 않은 상태를 의미합니다.

3 단계. 메시지 유형 체크 및 메시지 처리
적절한 메시지 유형을 처리하는 것인지 확인하기 위해, IF 문장을 조합하여, 메시지 결과집합에 포함된 message_type_name 컬럼의 값을 체크합니다. 체크한 결과에 포함될 수 있는 메시지 유형에는 사전에 정의된 메시지 유형,
http://schemas.microsoft.com/SQL/ServiceBroker/Error 메시지 유형의 오류 메시지,
http://schemas.Microsoft.com/SQL/ServiceBroker/DialogTimer 메시지 유형의 대화 타임아웃 메시지,
http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog 메시지 유형의 대화종료 메시지가 있습니다.

4 단계. 대화를 종료하기 위해 END CONVERSATION 호출
서비스 공급자가 작업을 완료하면, END CONVERSATION 문장을 사용하여, 대화를 종료할 수 있습니다. END CONVERSATION 명령에 대한 구문은 다음과 같습니다.
END CONVERSATION conversation_handle
   [ [ WITH ERROR = failure_code DESCRIPTION = failure_text ]
     | [ WITH CLEANUP ] ]
conversation_handle 는 종료하고자 하는 대화에 대한 식별자를 지정합니다. WITH ERROR 절을 사용하여 오류 코드와 설명을 지정할 수 있습니다.

WITH CLEANUP 절은 대화 상대자에게 통지 없이 대화에 포함된 모든 메시지와 메타데이터를 삭제하기 위해서 사용합니다. SQL Server 는 대화를 구성하고 있는 엔드포인트와, 전송 큐에 포함된 대화에 대한 모든 메시지, 서비스 큐에 포함된 대화에 대한 모든 메시지를 삭제합니다.


[출처] DBGuide.net