Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 Service Broker在30分钟后在sys.conversation_终结点中保留已关闭的项目_Sql Server 2008_Service Broker - Fatal编程技术网

Sql server 2008 Service Broker在30分钟后在sys.conversation_终结点中保留已关闭的项目

Sql server 2008 Service Broker在30分钟后在sys.conversation_终结点中保留已关闭的项目,sql-server-2008,service-broker,Sql Server 2008,Service Broker,我使用内部激活设置了一个单机服务代理,代理正在处理放置在队列上的项目,并且似乎正在正确关闭对话(请参阅下面的配置文件详细信息) sys.conversation_端点中以CD关闭状态保留的一条记录,其安全时间戳将在未来30分钟内设置,但该记录永远不会被删除 我也有自己的日志来显示发生了什么唯一奇怪的是,启动器过程被调用时,会话句柄、消息类型和消息体(日志信息中的最后一项)的值为空 我已经包括了一个脚本(名称已更改,不表示实际名称),它将创建我正在使用的所有对象,为了模拟我如何使用它们,只需执行:

我使用内部激活设置了一个单机服务代理,代理正在处理放置在队列上的项目,并且似乎正在正确关闭对话(请参阅下面的配置文件详细信息)

sys.conversation_端点中以CD关闭状态保留的一条记录,其安全时间戳将在未来30分钟内设置,但该记录永远不会被删除

我也有自己的日志来显示发生了什么唯一奇怪的是,启动器过程被调用时,会话句柄、消息类型和消息体(日志信息中的最后一项)的值为空

我已经包括了一个脚本(名称已更改,不表示实际名称),它将创建我正在使用的所有对象,为了模拟我如何使用它们,只需执行:

dbo.usp_QueueRequest 2, null, 'Trial'
这应该会给你我一直看到的相同结果

跟踪:

EventClass                TextData              SPID Event Sequence EventSubClass
Broker:Activation                               30   1394           1 - Start
Broker:Conversation       CONVERSING            30   1395           1 - SEND Message
Broker:Message Classify                         30   1396           1 - Local
Broker:Conversation       CONVERSING            30   1397           6 - Received Sequenced Message
Broker:Activation                               31   1398           1 - Start
Broker:Conversation       DISCONNECTED_OUTBOUND 31   1399           2 - END CONVERSATION
Broker:Conversation Group                       31   1400           2 - Drop
Broker:Message Classify                         31   1401           1 - Local
Broker:Conversation       DISCONNECTED_INBOUND  31   1402           7 - Received END CONVERSATION
Broker:Conversation       CLOSED                31   1403           10 - Received END CONVERSATION Ack
Broker:Conversation       CLOSED                30   1404           2 - END CONVERSATION
Broker:Conversation Group                       30   1405           2 - Drop
Broker:Activation                               30   1406           2 - Ended
Broker:Activation                               31   1407           2 - Ended
我的日志

Sequence Description
1        Target activation for message type: RequestMessage
2        Call fake processing procedure
3        In fake processing procedure
4        Send ReplyMessage for conversation 8B355311-5D9F-E111-93EC-A4BADBFBB13B
5        Initiator activation
6        Initiator conversation 88355311-5D9F-E111-93EC-A4BADBFBB13B message type: ReplyMessage
7        Initiator received reply from target, end converstion
8        Initiator activation
9        Target activation for message type: http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog
10       Target received end dialog
11       Initiator No conversation message type:No message type
sys.conversation_端点记录(缩短)

创建对象的脚本(名称已更改,而不是实际名称)


根据我的理解和经验,一旦谈话结束,你就什么都不用做。SQL Server将自动为您管理对话的清理


如果你真的想让那些争吵消失;当您调用
结束对话
时,您应该在
中附加CLEANUP
,这将导致SQL Server将对话作为该事务的一部分进行清理。然而,我的理解是,通过让SQL Server为您管理清理,您可以获得更好的性能。

Hi Joseph,我的理解略有不同,因为您不必使用清理结束对话,因为只有在对话无法正常完成时才应该使用清理(MSDN文章)。在这种情况下,我已经概述了对话的双方通话结束对话,正确地将记录放入自动删除的正确状态。虽然这并不完全适用于您的场景,但我所看到的最接近这种行为的情况如下:(见Remus Rusanu的帖子)顺便说一句,消息正文为空的原因是,initator激活过程与目标激活过程不遵循相同的模式。(如果启动器存储过程收到0条消息,则不会退出)
conversation_handle                     is_initiator state  state_desc far_service      security_timestamp      dialog_timer
8B355311-5D9F-E111-93EC-A4BADBFBB13B    0            CD     CLOSED     InitiatorService 2012-05-16 14:13:38.923 1900-01-01 00:00:00.000
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Log]') AND type in (N'U'))
DROP TABLE [dbo].[Log]
GO

CREATE TABLE [dbo].[Log](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Description] [varchar](max) NULL,
    [DateTime] [date] NULL  DEFAULT (getdate()))

GO

IF  EXISTS (SELECT * FROM sys.database_principals WHERE name = N'BrokerUser')
DROP USER [BrokerUser]
GO

CREATE USER [BrokerUser] WITHOUT LOGIN WITH DEFAULT_SCHEMA=[dbo]
GO

IF NOT EXISTS (SELECT * FROM sys.service_message_types WHERE name = N'RequestMessage')  
    CREATE MESSAGE TYPE [RequestMessage] VALIDATION = WELL_FORMED_XML

IF NOT EXISTS (SELECT * FROM sys.service_message_types WHERE name = N'AReplyMessage')   
    CREATE MESSAGE TYPE [ReplyMessage] VALIDATION = WELL_FORMED_XML
GO

IF NOT EXISTS (SELECT * FROM sys.service_contracts WHERE name =N'MessageContract')
    CREATE CONTRACT [MessageContract]
        ([RequestMessage] SENT BY INITIATOR,
        [ReplyMessage] SENT BY TARGET)
GO  

IF NOT EXISTS (SELECT * FROM sys.service_queues WHERE name = N'TargetQueue')
    CREATE QUEUE TargetQueue
GO

IF EXISTS (SELECT * FROM sys.service_queues WHERE name = N'TargetQueue')
    GRANT RECEIVE ON [TargetQueue] TO [BrokerUser]
GO

IF NOT EXISTS (SELECT * FROM sys.services WHERE name = N'TargetService')
    CREATE SERVICE [TargetService]
                   ON QUEUE TargetQueue
                   ([MessageContract])
GO

IF EXISTS (SELECT * FROM sys.services WHERE name = N'TargetService')
    GRANT SEND ON SERVICE::[TargetService] TO [BrokerUser]
GO

IF NOT EXISTS (SELECT * FROM sys.service_queues WHERE name = N'InitiatorQueue')
    CREATE QUEUE InitiatorQueue;
GO  

IF EXISTS (SELECT * FROM sys.service_queues WHERE name = N'InitiatorQueue')
    GRANT RECEIVE ON [InitiatorQueue] TO [BrokerUser]
GO

IF NOT EXISTS (SELECT * FROM sys.services WHERE name = N'InitiatorService')
CREATE SERVICE [InitiatorService]
               ON QUEUE InitiatorQueue
GO

IF EXISTS (SELECT * FROM sys.services WHERE name = N'InitiatorService') 
    GRANT SEND ON SERVICE::[InitiatorService] TO [BrokerUser]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_FakeProcessing]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_FakeProcessing]
GO

CREATE PROCEDURE [dbo].[usp_FakeProcessing]
AS
BEGIN

    insert [Log] ([Description])
    VALUES ('In fake processing procedure');

END
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_TargetActivation]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_TargetActivation]
GO

CREATE PROCEDURE [dbo].[usp_TargetActivation]
AS
  DECLARE @Handle UNIQUEIDENTIFIER;
  DECLARE @Message XML;
  DECLARE @MessageType sysname;

  WHILE (1=1)
  BEGIN

    BEGIN TRANSACTION;

    WAITFOR
    ( RECEIVE TOP(1)
        @Handle = conversation_handle,
        @Message = message_body,
        @MessageType = message_type_name
      FROM TargetQueue
    ), TIMEOUT 5000;

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


    INSERT [Log] ([Description]) VALUES ('Target activation for message type: ' + + COALESCE(@MessageType,'No message type'))

    -- it's an error message (some error occurred on the initiator side).  
    --This type of message is automatically created by SB when an END CONVERSATION command is executed with the WITH ERROR clause for the initiator
    IF @MessageType =N'http://schemas.microsoft.com/SQL/ServiceBroker/Error' 
    BEGIN

        ROLLBACK TRANSACTION; -- roll back the message transaction.  In this example there was nothing done to roll back but it is good practice
                              -- in the event of an error

        INSERT [Log] ([Description]) VALUES ('Error occured with SB')
       END CONVERSATION @Handle; -- and end the conversation (dialog) on this side (target)
       BREAK; -- break out of the loop (and end the stored proc)

    END
    ELSE IF @MessageType = N'RequestMessage'
    BEGIN


        INSERT [Log] ([Description]) VALUES ('Call fake procedure')

        EXEC [usp_FakeProcessing]; 

        INSERT [Log] ([Description]) VALUES ('Add reply message for conversation ' + CAST(@Handle AS varchar(80)) + ' with message : ' + CAST(@Message as VARCHAR(4000)));

        SEND ON CONVERSATION @Handle
                MESSAGE TYPE [ReplyMessage] (@message)

    END
    ELSE IF @MessageType = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
    BEGIN
        INSERT [Log] ([Description]) VALUES ('Target received end dialog')
       END CONVERSATION @Handle;
    END    

    COMMIT TRANSACTION;

  END
GO


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_InitiatorActivation]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_InitiatorActivation]
GO

CREATE PROCEDURE [dbo].[usp_InitiatorActivation]
AS

  DECLARE @Handle UNIQUEIDENTIFIER;
  DECLARE @Message XML;
  DECLARE @MessageType sysname;

BEGIN

    INSERT [Log] ([Description]) VALUES ('Initiator activation')

    WAITFOR
    ( RECEIVE TOP(1)
        @Handle = conversation_handle,
        @Message = message_body,
        @MessageType = message_type_name
      FROM InitiatorQueue
    ), TIMEOUT 5000;


    INSERT [Log] ([Description]) VALUES ('Initiator ' + ISNULL(CAST(@Handle AS VARCHAR(100)) , 'No handle') + ' message type:' + COALESCE(@MessageType,'No message type') + ' Body: ' + COALESCE(CAST(@Message AS varchar(1000)),'No body'))

    IF  @Handle IS NOT NULL
    BEGIN

        IF @MessageType = N'ReplyMessage'
        BEGIN
            INSERT [Log] ([Description]) VALUES ('Initiator received reply from target, end converstion')
           END CONVERSATION @Handle;
        END  


        IF @MessageType = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
        BEGIN
            INSERT [Log] ([Description]) VALUES ('Initiator received end dialog message')
           END CONVERSATION @Handle;
        END  
    END
END
GO

GRANT EXECUTE ON [usp_TargetActivation] to [BrokerUser]
GO

GRANT EXECUTE ON [usp_InitiatorActivation] to [BrokerUser]
GO

IF EXISTS (SELECT * FROM sys.service_queues WHERE name = N'TargetQueue')
ALTER QUEUE TargetQueue
    WITH ACTIVATION
    ( STATUS = ON,
      PROCEDURE_NAME = [usp_TargetActivation],
      MAX_QUEUE_READERS = 1,
      EXECUTE AS 'BrokerUser'
    );
GO

IF EXISTS (SELECT * FROM sys.service_queues WHERE name = N'InitiatorQueue')
ALTER QUEUE InitiatorQueue
    WITH ACTIVATION
    ( STATUS = ON,
      PROCEDURE_NAME = [usp_InitiatorActivation],
      MAX_QUEUE_READERS = 1,
      EXECUTE AS 'BrokerUser'
    );
GO


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_QueueRequest]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_QueueRequest]
GO

CREATE PROCEDURE [dbo].[usp_QueueRequest]
    @numericvalue INT,
    @StartDate DATE,
    @TriggeredBy VARCHAR(50)
AS
BEGIN
    DECLARE @Handle UNIQUEIDENTIFIER;
    DECLARE @RequestMsg NVARCHAR(100);

    DECLARE @MessageBody XML
    DEClare @Params TABLE
    (
        ReadingDate SMALLDATETIME,
        SiteNumber INT,
        TriggeredBy VARCHAR(50)
    )
    INSERT INTO @Params(ReadingDate,SiteNumber, TriggeredBy)
    VALUES(@StartDate, @numericvalue, @TriggeredBy)

    SELECT @MessageBody = (SELECT * FROM @Params FOR XML PATH ('Params'), TYPE);

    BEGIN TRANSACTION;

    BEGIN DIALOG @Handle
            FROM SERVICE [InitiatorService]
            TO SERVICE  'TargetService'
            ON CONTRACT [MessageContract]
            WITH ENCRYPTION = OFF;

    SEND ON CONVERSATION @Handle
         MESSAGE TYPE 
            [RequestMessage]
            (@MessageBody);

    COMMIT TRANSACTION;
END
GO