2

我敢肯定我不是第一个这么说的人,但是关于 Windows Server 的 Service Bus 1.0 的细节方面的文档严重缺乏......我希望一些 MS 内部人员可以帮助清除一个几件事情...

  1. 使用队列/主题的服务是否在隐式环境事务中运行?例如,考虑以下代码片段:

    [ServiceBehavior]
    public class MySbService : IDoWork
    {
        [OperationBehavior]
        void DoSomeWork(WorkRequest request)
        {
            DoDatabaseWork();
    
            DoMoreDatabaseWork();
        }
    }
    

    在上面的示例中,如果没有创建明确的,如果抛出异常TransactionScopeDoDatabaseWork()被提交吗?DoMoreDatabaseWork()换句话说,排队操作是否在 MSDTC 跟踪的环境事务下运行?

  2. 如果抛出异常,Service Bus 1.0 队列是否会自动重试(如 MSMQ 那样)?我问是因为我没有遇到任何指定重试行.config为的设置。此外,当使用我看到的最接近的东西netMessagingBinding创建队列时。来自 MSMQ 背景,我习惯于看到异常消息出现在重试/毒药队列中。在 Service Bus 1.0 世界中是否有与此同义的东西?Service Bus ExplorerMaxDeliveryAttempt

先感谢您

更新:

请在下面查看我的答案以获取更多详细信息。我正在修改这个问题以提出以下问题:

是否可以使用带有服务总线 1.0 的合同优先、IIS 托管的 WCF 来“覆盖”客户端在事务中发送到服务总线?如果是这样,怎么做?另外,使用的机制是什么?

4

2 回答 2

2

我相信我已经找到了我的两个问题的答案......

  1. 对于Transactional运营,我不相信存在“环境”交易。我已经通过在数据库操作后简单地抛出异常来证明这一点,果然,无论如何数据都已提交。我想知道是否有声明事务范围的首选方法,即:

    [OperationBehavior(TransactionScopeRequired = true)]
    public void MyServiceOperation(){ ... }
    
    //or using the TransactionScope
    
    public void MyServiceOperation()
    {
        using(var transScope = new TransactionScope(...)){ ... }
    }
    
  2. ReceiveContext对于重试功能,您似乎需要启用以下博客

    [ServiceContract]
    public interface IMyService
    {
        [OperationContract(IsOneWay=true)]
        [ReceiveContextEnabled(ManualControl = true)]
        void MyServiceOperation();
    
    // and in the service implementation:
    
    [OperationBehavior]
    public void MyServiceOperation()
    {
        var incomingProperties = OperationContext.Current.IncomingMessageProperties;
        var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;
    
        //Complete the Message
    
        ReceiveContext receiveContext;
        if (ReceiveContext.TryGet(incomingProperties, out receiveContext))
        {
            //Do Something                
    
            receiveContext.Complete(TimeSpan.FromSeconds(10.0d));
        }
    
        else
        {
            throw new InvalidOperationException("...");
        }
    }
    

更新:

在深入挖掘之后,我发现如果您使用普通的、合同优先、IIS 托管、带有 Service Bus 1.0 的 WCF,那么 OperationContext 完成并不是一个真正的选择(不知道为什么,但我我希望有人能对此有所了解)

我发现关于事务行为的唯一理智选项如下:

[OperationBehavior]
public void MyServiceOperation()
{
    using(var transScope = new TransactionScope(...))
    {
        DbWork();
        transScope.Complete();
    }

    Client.SendToServiceBus(); // <-- Cannot be part of transaction, otherwise
                               //     exceptions will be thrown!
}

问题仍然是,这种模式与 MSMQ 不同,如果将消息发送到服务总线失败,则不允许回滚整个操作。(当然,除非有人知道得更好……)

这也意味着您被迫滚动自己的重试逻辑,并且可能有一些机制在下一步验证上一步是否已提交。呸!

据我了解,工作流服务和直接处理代理消息为您提供了一些开箱即用的重试功能。但是,如果您通过 AppFabric 使用 IIS 托管您的工作流服务,那么微软不知何故想出了如何让事务覆盖发送到服务总线。(如果有人知道那个机制是什么,请告诉我!)

于 2013-03-20T16:01:36.540 回答
0

对于#2,您可以通过瞬态故障处理框架重试

http://windowsazurecat.com/2011/02/transient-fault-handling-framework/

通读本文档以了解与服务总线相关的用法。

http://social.technet.microsoft.com/wiki/contents/articles/best-practices-for-leveraging-windows-azure-service-bus-brokered-messaging.aspx?Sort=MostRecent&PageIndex=1

于 2013-04-23T18:10:37.437 回答