【问题标题】:Service Broker And Web services服务代理和 Web 服务
【发布时间】:2024-04-20 11:35:02
【问题描述】:

我想实现一个调用 Web 服务的存储过程(在服务代理基础设施内)。我查看了 Aschenbrenner 关于 Service Broker 的书中的一些示例。但是,我没有找到任何带有 Web 服务调用的内容。有人可以帮忙吗?

谢谢 Sqlbs

【问题讨论】:

    标签: service service-broker


    【解决方案1】:

    我们在我的公司有一个类似的任务,并想出一个最佳的解决方案是使用带有外部激活器的异步触发器,它从 .NET 调用 web 服务并在成功调用后将消息出队。这意味着您创建了一个常规数据库触发器,该触发器将消息发送到服务代理队列以进行异步处理。 AKA 异步触发器。这是克劳斯的书第 10 章中的一个示例

    -- Create the trigger written with T-SQL
    CREATE TRIGGER OnCustomerInserted ON Customers FOR INSERT
    AS
    DECLARE @conversationHandle UNIQUEIDENTIFIER
    DECLARE @fromService SYSNAME
    DECLARE @toService SYSNAME
    DECLARE @onContract SYSNAME
    DECLARE @messageBody XML
    
    SET @fromService = 'CustomerInsertedClient'
    SET @toService = 'CustomerInsertedService'
    SET @onContract = 'http://ssb.csharp.at/SSB_Book/c10/CustomerInsertContract'
    
    -- Check if there is already an ongoing conversation with the TargetService
    SELECT @conversationHandle = ConversationHandle FROM SessionConversations
        WHERE SPID = @@SPID
        AND FromService = @fromService
        AND ToService = @toService
        AND OnContract = @onContract
    
    IF @conversationHandle IS NULL
    BEGIN
        -- We have to begin a new Service Broker conversation with the TargetService
        BEGIN DIALOG CONVERSATION @conversationHandle
            FROM SERVICE @fromService
            TO SERVICE @toService
            ON CONTRACT @onContract
            WITH ENCRYPTION = OFF;
    
        -- Create the dialog timer for ending the ongoing conversation
        BEGIN CONVERSATION TIMER (@conversationHandle) TIMEOUT = 5;
    
        -- Store the ongoing conversation for further use
        INSERT INTO SessionConversations (SPID, FromService, ToService, OnContract, ConversationHandle)
        VALUES
        (
            @@SPID,
            @fromService,
            @toService,
            @onContract,
            @conversationHandle
        )
    END
    
    -- Construct the request message
    SET @messageBody = (SELECT * FROM INSERTED FOR XML AUTO, ELEMENTS);
    
    -- Send the message to the TargetService
    ;SEND ON CONVERSATION @conversationHandle
    MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c10/CustomerInsertedRequestMessage] (@messageBody);
    

    我们决定最好将处理卸载到 sql server 之外,而不是使用通过托管代码(内部激活)调用 Web 服务的存储过程。并发现了这个由微软创建的不错的小工具 - External Activator 当队列中有新消息时,它将侦听激活队列并启动应用程序。具体实现请参考本书中克劳斯的第 4 章。

    【讨论】:

      【解决方案2】:

      我会制作位于服务代理末端的 Windows 服务(并像在任何 win 应用程序中一样调用 Web 服务)。不知何故,不要认为从 db 调用 Web 服务是个好主意。

      可以找到外部激活器here。并下载服务代理接口/外部激活器here。服务代理界面很棒!易于使用。

      【讨论】:

        【解决方案3】:

        请参阅第 10 章中的第一个示例。如果您的问题是关于实现 Web 服务调用的详细信息,请使用适当的 Web 服务标签而不是服务代理来标记问题。

        【讨论】:

        • 您好,感谢您的留言。我看了一下例子。它是关于在服务代理基础设施中调用 Web 服务。我真正需要的是这样的:插入/更新到表的行->插入/更新触发器触发->触发器将消息写入服务代理队列->由SQL Server激活的存储过程->存储过程调用Web服务->对话结束.任何的想法? Sqlbs