Service Broker内部激活中毒 - 在哪里?

时间:2015-09-14 20:20:55

标签: sql-server stored-procedures service-broker

我正在体验有毒信息,我不知道为什么。

我的经纪人设置如下:

CREATE MESSAGE TYPE
  [//DB/Schema/RequestMessage]
  VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
  [//DB/Schema/ReplyMessage]
  VALIDATION = WELL_FORMED_XML;

CREATE CONTRACT [//DB/Schema/Contract](
  [//DB/Schema/RequestMessage] SENT BY INITIATOR,
  [//DB/Schema/ReplyMessage] SENT BY TARGET
)

CREATE QUEUE Schema.TargetQueue

CREATE SERVICE [//DB/Schema/TargetService]
ON QUEUE Schema.TargetQueue (
  [//DB/Schema/Method3Contract]
)

CREATE QUEUE Schema.InitiatorQueue

CREATE SERVICE [//DB/Schema/InitiatorService]
ON QUEUE Schema.InitiatorQueue

然后我有我的内部激活程序:

CREATE PROCEDURE Schema.Import
AS

DECLARE @RequestHandle UNIQUEIDENTIFIER;
DECLARE @RequestMessage VARCHAR(8);
DECLARE @RequestMessageName sysname;

WHILE (1=1)
BEGIN
  BEGIN TRANSACTION;

  WAITFOR (
    RECEIVE TOP(1)
      @RequestHandle = conversation_handle,
      @RequestMessage = message_body,
      @RequestMessageName = message_type_name
    FROM
      Schema.TargetQueue

  ), TIMEOUT 5000;


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

  EXEC Schema.ImportStep1 @ID = @RequestMessage;
  --EXEC Schema.ImportStep2 @ID = @RequestMessage;

  END CONVERSATION @RequestHandle;

  COMMIT TRANSACTION;
END

我的激活是通过以下方式启用的:

ALTER QUEUE Schema.TargetQueue
    WITH 
    STATUS = ON,
    ACTIVATION 
    ( STATUS = ON,
      PROCEDURE_NAME = Schema.Import,
      MAX_QUEUE_READERS = 10,
      EXECUTE AS SELF
    )

我使用此存储过程启动此过程

CREATE PROCEDURE Schema.ImportStart
AS
BEGIN
  DECLARE @ID VARCHAR(8);

  DECLARE Cursor CURSOR FOR 
    SELECT ID FROM OtherDatabase.OtherSchema.ImportTable
    EXCEPT
    SELECT ID FROM Table

  OPEN Cursor;
  FETCH NEXT FROM Cursor INTO @ID;
  WHILE @@FETCH_STATUS = 0
  BEGIN
    DECLARE @InitiateHandle UNIQUEIDENTIFIER;
    DECLARE @RequestMessage VARCHAR(8);

    BEGIN TRANSACTION;

    BEGIN DIALOG
      @InitiateHandle
    FROM SERVICE
      [//DB/Schema/InitiatorService]
    TO SERVICE
      N'//DB/Schema/TargetService'
    ON CONTRACT
      [//DB/Schema/Contract]
    WITH
      ENCRYPTION = OFF;

    SELECT @RequestMessage = @ID;

    SEND ON CONVERSATION
      @InitiateHandle
    MESSAGE TYPE
      [//DB/Schema/RequestMessage]
      (@RequestMessage);

    COMMIT TRANSACTION;

    FETCH NEXT FROM Cursor INTO @ID;
  END
  CLOSE Cursor;
  DEALLOCATE Cursor;
END

这应该如何运作:

  • 我执行ImportStart
  • 生成每个ID的消息
  • 内部激活使导入步骤执行

相反,我收到了有害消息,队列被禁用了。

但是,

  • 我将Schema.TargetQue Activation设置为OFF
  • EXEC schema.ImportStart
  • EXEC架构。手动导入

工作正常。

任何人的见解?

1 个答案:

答案 0 :(得分:1)

好:

  • 您的邮件类型定义为well_formed_xml,但您将varchar(8)作为邮件正文发送。它确实有用吗?
  • 您使用[//DB/Schema/Method3Contract]作为目标队列,但不定义它。拼写错误,很有可能。
  • 您在队列激活中指定EXECUTE AS SELF。 BOL对这个案子说了一些神秘的事情:
      

    SELF
      指定存储过程作为当前用户执行。 (执行此ALTER QUEUE语句的数据库主体。)

我不太确定我理解所引用的陈述,因为它显然与你的经历相矛盾。如果它是你的用户帐户,一切都应该没问题,因为你似乎拥有完成这项工作所需的所有权限。

所以,以防万一 - 谁是Schema架构的所有者?这个校长拥有什么权限?而且,如果不是你,谁执行alter queue声明(以及为什么)?

无法访问日志,诊断问题要困难得多,但我首先要创建一个权限与您的权限相同的新用户帐户,将其设置为Schema架构的所有者,然后慢慢处理它向下,撤消不必要的权限,直到它中断。当然,假设它会起作用。