2013-07-24 2 views
0

SQL Server 인스턴스가있는 서버 A와 B가 있습니다. TRANSPORT를 통한 경로로 작성된 서비스가 있습니다. 메시지를 수신했습니다. B에서 내부 활성화를 만들려고하지만 대기열이 멈 춥니 다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 수정 됨. A에서 B로 보낸 각 메시지에 대해 5 부씩 반환됩니다.Service broker : TRANSPORT 경로를 통한 두 인스턴스의 내부 활성화

서버 A

 USE master 
    GO 

    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'PAROLPAROL123' 

    CREATE CERTIFICATE [GA_SERVER] 
    WITH SUBJECT = 'GA_SERVER'; 
    GO 

    CREATE ENDPOINT BROKER 
     STATE=STARTED 
     AS TCP (LISTENER_PORT = 4022) 
     FOR SERVICE_BROKER 
     (
     AUTHENTICATION = CERTIFICATE [GA_SERVER] 
     ); 

    GRANT CONNECT ON ENDPOINT::BROKER TO [PUBLIC]; 
    GO 

    CREATE DATABASE DB_A 
    GO 

    ALTER DATABASE DB_A 
    SET ENABLE_BROKER 
    WITH ROLLBACK IMMEDIATE; 

    GO 

    USE DB_A; 
    CREATE MESSAGE TYPE RequestMT 
    validation=NONE; 

    CREATE MESSAGE TYPE ResponseMT 
    validation=NONE; 

    CREATE CONTRACT GAContract 
    (
     RequestMT 
     SENT BY INITIATOR, 
     ResponseMT 
     SENT BY TARGET 
    ); 

    CREATE QUEUE GAQueue 
    WITH status = ON; 

    CREATE SERVICE [tcp://10.10.100.56:4022/GAservice] 
    ON QUEUE GAQueue (GAContract) 
    GO 

    GRANT SEND ON SERVICE::[tcp://10.10.100.56:4022/GAservice] TO [PUBLIC] 
    CREATE ROUTE transport WITH ADDRESS = 'TRANSPORT'; 

    GO 
CREATE TABLE [dbo.t1](
    [mes] [nvarchar](max) NULL 
) ON [PRIMARY]; 

GO 

CREATE PROCEDURE ActivProcA 
AS 
BEGIN 
SET NOCOUNT ON 
    DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER; 
    DECLARE @RecvReqMsg NVARCHAR(1000); 
    DECLARE @RecvReqMsgName sysname; 

BEGIN TRANSACTION; 
WHILE (1=1) 
BEGIN 

WAITFOR 
(RECEIVE TOP(1) 
     @RecvReqDlgHandle = conversation_handle, 
     @RecvReqMsg = message_body, 
     @RecvReqMsgName = message_type_name 
    FROM GAQueue 
), TIMEOUT 5000; 
    IF (@@ROWCOUNT = 0) 
    BEGIN 
     ROLLBACK TRANSACTION; 
--  END CONVERSATION @RecvReqDlgHandle; 
     BREAK; 
    END 

    IF @RecvReqMsgName = 
     N'ResponseMT' 
    BEGIN 
    INSERT INTO [dbo.t1] (mes) VALUES (N'back to A from B ('+ CAST(CURRENT_TIMESTAMP AS NVARCHAR)+N'):'[email protected]); 
    END 
    ELSE 
     END CONVERSATION @RecvReqDlgHandle; 
    COMMIT TRANSACTION;  
SET NOCOUNT OFF; 
END; 
END; 

GO 

ALTER QUEUE GAQueue 
    WITH 
    STATUS = ON, 
    ACTIVATION 
    (STATUS = ON, 
     PROCEDURE_NAME = ActivProcA, 
     MAX_QUEUE_READERS = 10, 
     EXECUTE AS SELF 
    ); 
GO 

서버 B

USE MASTER 
GO 

CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'PAROLPAROL123' 

CREATE CERTIFICATE [GOS_SERVER] 
WITH SUBJECT = 'GOS_SERVER'; 
GO 

CREATE ENDPOINT BROKER 
    STATE=STARTED 
    AS TCP (LISTENER_PORT = 4022) 
    FOR SERVICE_BROKER 
    (
    AUTHENTICATION = CERTIFICATE [GOS_SERVER], 
    ); 

GRANT CONNECT ON ENDPOINT::BROKER TO [PUBLIC]; 
GO 

CREATE DATABASE DB_B_1 
GO 

ALTER DATABASE DB_B_1 
SET ENABLE_BROKER 
WITH ROLLBACK IMMEDIATE; 
GO 

USE DB_B_1; 
CREATE MESSAGE TYPE RequestMT 
validation=NONE; 

CREATE MESSAGE TYPE ResponseMT 
validation=NONE; 

CREATE CONTRACT GAContract 
(
    RequestMT 
    SENT BY INITIATOR, 
    ResponseMT 
    SENT BY TARGET 
); 

CREATE QUEUE GAQueue 
WITH status = OFF; 

GO 

CREATE SERVICE [tcp://10.10.100.78:4022/GOS_DB_B_1_service] 
ON QUEUE GAQueue (GAContract) 
GO 

GRANT SEND ON SERVICE::[tcp://10.10.100.78:4022/GOS_DB_B_1_service] TO [PUBLIC] 

CREATE ROUTE transport WITH ADDRESS = 'TRANSPORT'; 

GO 

CREATE TABLE [dbo.t1](
    [mes] [nvarchar](max) NULL 
) ON [PRIMARY]; 
GO 

CREATE PROCEDURE ActivProcB 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER; 
    DECLARE @RecvReqMsg NVARCHAR(100); 
    DECLARE @RecvReqMsgName sysname; 

    WHILE (1=1) 
    BEGIN 
    BEGIN TRANSACTION; 

    WAITFOR 
    (RECEIVE TOP(1) 
     @RecvReqDlgHandle = conversation_handle, 
     @RecvReqMsg = message_body, 
     @RecvReqMsgName = message_type_name 
     FROM GAQueue 
    ), TIMEOUT 5000; 

    IF (@@ROWCOUNT = 0) 
    BEGIN 
     ROLLBACK TRANSACTION; 
     BREAK; 
    END 

    IF @RecvReqMsgName = 
     N'RequestMT' 
    BEGIN 
     INSERT INTO [dbo.t1] (mes) VALUES (N'('+ CAST(CURRENT_TIMESTAMP AS NVARCHAR)+N'):'[email protected]);    
     DECLARE @Msg NVARCHAR(100); 
     DECLARE @I INT; 
     SET @I = 1; 
     WHILE @I<6 
     BEGIN 
     SET @Msg = N'<MsgFromB1>'+CAST (@I AS NVARCHAR(1))+N' ('+CAST(CURRENT_TIMESTAMP AS NVARCHAR)+N')</MsgFromB1>'; 
     SEND ON CONVERSATION @RecvReqDlgHandle 
       MESSAGE TYPE 
       ResponseMT 
       (@Msg);  
     SET @I = @I+1;  
     END     
    END;  
    COMMIT TRANSACTION;  
    END 

SET NOCOUNT OFF; 
END; 
GO 

ALTER QUEUE GAQueue 
    WITH 
    STATUS = ON, 
    ACTIVATION 
    (STATUS = ON, 
     PROCEDURE_NAME = ActivProcB, 
     MAX_QUEUE_READERS = 10, 
     EXECUTE AS SELF 
    ); 
GO 

서버 A

USE DB_A 

DECLARE @ConversationHandle UNIQUEIDENTIFIER; 
DECLARE @RequestMsg NVARCHAR(4000); 

BEGIN TRANSACTION 

BEGIN DIALOG @ConversationHandle 
FROM SERVICE [tcp://10.10.100.56:4022/GAservice] 
TO SERVICE 'tcp://10.10.100.78:4022/GOS_DB_B_1_service' 
ON CONTRACT GAContract 
WITH ENCRYPTION = OFF; 

SELECT @RequestMsg = 
     N'<RequestMsg>test1</RequestMsg>'; 

SEND 
ON CONVERSATION @ConversationHandle 
    MESSAGE TYPE RequestMT 
    (@RequestMsg); 

COMMIT TRANSACTION; 

GO 
+0

로그를 보셨습니까? 문제와 관련하여 어떤 이벤트가 있습니까? – Serg

답변

1

내가 B에 내부 활성화를 만들려고 해요,하지만 큐가

을 중지

이것은 독이있는 메시지 탐지가 시작될 가능성이 높습니다. 활성화 된 프로 시저가 예외를 발생시키고 롤백을 유발하고 있음을 의미합니다. 이 경우 오류 메시지를 포함한 프로 시저의 출력이 ERRORLOG에 기록됩니다. 그것이 당신이 볼 필요가있는 곳입니다.

정품 인증을 사용하지 않도록 설정하고 쿼리 창에서 수동으로 프로 시저를 호출하여이 절차의 문제를 해결할 수도 있습니다. 이렇게하면 오류 메시지/예외가 직접 표시됩니다. 활성화 된 프로 시저와 동일한 컨텍스트에서 실행하려면 프로 시저를 호출하기 전에 EXECUTE AS USER = 'dbo'을 실행하십시오.

Troubleshooting Activation Stored Procedures을 참조하십시오.

+0

Remus Rusanu, 답장과 유용한 링크에 감사드립니다. 제 부주의입니다 - 저는 [dbo.t1]에 [dbo.t1]을 넣고 활성화 절차를 밟았습니다. – yuriy