首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当关闭队列上的XML验证时,Service激活输出“消息体可能不是空”

当关闭队列上的XML验证时,Service激活输出“消息体可能不是空”
EN

Stack Overflow用户
提问于 2014-11-28 13:12:58
回答 1查看 2.1K关注 0票数 0

在2014年的MS SQL Server上运行Service从测试切换到活动正在产生一个新的错误:

在队列'dbo.usp_CalcPrice‘上运行的激活proc 'dbo.CalcPriceDataQueue’输出如下:‘消息体可能不是NULL。指定了一个零长度UNICODE或二进制字符串。’

测试版本与Live的不同之处在于,dbo.usp_CalcPrice中使用的消息类型不再具有changes = XXXXX,但是性能上的更改是对changes= NONE的更改。

我添加了一个表来转储dbo.usp_CalcPrice从队列中接收到的存储过程,它看起来很好,可以这样做:

代码语言:javascript
运行
复制
  WHILE (1 = 1) 
  BEGIN -- Receive the next available message from the queue 
    WAITFOR ( 
             RECEIVE TOP(1)     
             @message_body = CAST(message_body AS XML),     
             @dialog = conversation_handle
        FROM [dbo].[CalcPriceDataQueue]), TIMEOUT 50    
        IF (@@ROWCOUNT = 0 OR @message_body IS NULL) 
        BEGIN 
            break
        END 
        ELSE 
        BEGIN 
            SET @XmlBody = CAST(@message_body AS Nvarchar(max))
            INSERT INTO dbo.SB_Tester (XmlBody)
            VALUES(@XmlBody)
            ...

在一个简单的测试中,队列获得6-8k条目,在测试服务器上,没有错误,但是在运行时,每个条目需要2-5秒,而windows事件查看器在每个条目(上面的条目)中得到一个错误,在dbo.SB_Tester中,我为队列中的每个条目提供了一个好看的XML条目,无论是在测试中还是在活动中。

更多信息:

@@Version: Microsoft 2014 - 12.0.2254.0 (X64) 2014年7月25日18:52:51版权(c)微软公司企业版(64位) Windows 6.3 (Build 9600:)

它们被维护,所以版本总是相同的。

发送到队列的代码:

代码语言:javascript
运行
复制
DECLARE @MessageBody XML
SET @MessageBody = N'<Calc 
                        PartId="'           + @PartId +'"
                        CustomerId="'       + @CustId + '"
                        PriceRuleId="'      + @RuleId + '"
                        BaseSalesPrice="'   + @BaseSalesPrice + '"
                        CostPrice="'        + @CostPrice + '"
                        MinDB="'            + @MinDB + '"
                        IgnoreMinDB="'      + @IgnoreMinDB + '"
                        NoPriceRaising="'   + @NoPriceRaising + '"
                        Priority="'         + @Priority + '"
                        TargetPrice="'      + @TargetPrice + '"
                        ChangeType="'       + @ChangeType + '"
                        Change="'           + @Change + '"
                    />'

--PRINT CONVERT(Nvarchar(max), @MessageBody)

IF (@MessageBody IS NOT NULL)  
    BEGIN 
        DECLARE @Handle UNIQUEIDENTIFIER;   
        BEGIN DIALOG CONVERSATION @Handle
        FROM SERVICE [PriceCalcServiceSource]
        TO SERVICE   'PriceCalcServiceSink'
        ON CONTRACT [CalcPriceDataContract]
        WITH ENCRYPTION = OFF;   
        SEND ON CONVERSATION @Handle   
        MESSAGE TYPE [PriceData](@MessageBody);
    END

队列和msg创建:

代码语言:javascript
运行
复制
CREATE MESSAGE TYPE [PriceData] VALIDATION = NONE
GO

CREATE CONTRACT [CalcPriceDataContract] ([PriceData] SENT BY INITIATOR)
GO

CREATE QUEUE [dbo].[CalcPriceDataQueue] WITH STATUS = ON ,
    RETENTION = OFF , 
    ACTIVATION (STATUS = ON , 
                PROCEDURE_NAME = [dbo].[usp_CalcPrice] , 
                MAX_QUEUE_READERS = 40 , 
                EXECUTE AS OWNER  ), 
    POISON_MESSAGE_HANDLING (STATUS = ON)  
    ON [PRIMARY] 
GO

在测试服务器上创建消息:

代码语言:javascript
运行
复制
CREATE MESSAGE TYPE [PriceData]
VALIDATION = VALID_XML WITH SCHEMA COLLECTION dbo.PriceData

有人知道这个问题的原因吗?任何帮助都是非常感谢的:)

/Grue

EN

回答 1

Stack Overflow用户

发布于 2020-09-02 17:05:34

我的派对有点晚了,但我对Service也有同样的问题。当我们的大型机软件试图将数据插入Server数据库时,insert被取消,日志文件具有相同的消息。我从负责大型机的企业那里得到的建议是修改目标表上的触发器,以便在开始事务之前检查插入的信息是否存在。我的扳机现在是这样的:

代码语言:javascript
运行
复制
ALTER TRIGGER [dbo].[OnPedidoCompraInserted] ON [dbo].[PEDIDO_COMPRA] FOR INSERT
AS
BEGIN
    IF EXISTS (SELECT * FROM inserted) -- this is the verification he recommended me to add
    begin
        BEGIN TRANSACTION;
        DECLARE @ch UNIQUEIDENTIFIER
        DECLARE @messageBody NVARCHAR(MAX);
 
        BEGIN DIALOG CONVERSATION @ch
        FROM SERVICE [InitPedidoCompraService]
        TO SERVICE 'TargetPedidoCompraService'
        ON CONTRACT [http://ssb.csharp.at/PedidoCompraContract]
        WITH ENCRYPTION = OFF;
 
        -- Construct the request message
        SET @messageBody = (SELECT * from inserted FOR XML AUTO, ELEMENTS);
 
        -- Send the message to the TargetService
        ;SEND ON CONVERSATION @ch
        MESSAGE TYPE [http://ssb.csharp.at/RequestPedidoCompra] (@messageBody);
        COMMIT;
    END
end

我知道我迟到了,但我希望我能在将来帮助别人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27189449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档