Question

There are servers A and B with the SQL Server instances. There are created services with a route through TRANSPORT. Messages are successfully received. I'm trying to create an internal activation on B, but the queue stops. What am I doing wrong? Fixed. For each message sent from A to B is returned 5 copies.

SERVER 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'):'+@RecvReqMsg);  
    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

SERVER 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'):'+@RecvReqMsg);             
        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

SERVER 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
Was it helpful?

Solution

I'm trying to create an internal activation on B, but the queue stops

That's most likely poison message detection kicking in. It means your activated procedure is raising an exception and cause a rollback. When this happens the output of the procedure (including error messages) is logged into the ERRORLOG. That's where you need to look.

You can also attempt to troubleshoot the procedure by disabling activation and invoking the procedure manually from a query window. This way you'll see directly any error messages/exceptions. To execute under the same context as the activated procedure, issue an EXECUTE AS USER = 'dbo' before invoking the procedure.

See Troubleshooting Activation Stored Procedures.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top