Service Bus 1.0 for Windows Server Transaction/Error Handling

假如想象 提交于 2019-12-04 17:13:42

I believe I've found the answer to both of my questions...

  1. For Transactional operations, i don't believe there is an "ambient" transaction. I've proven this by simply throwing an exception after a database operation, and sure enough, the data is committed anyway. I would like to know if there's a preferred method of declaring transaction scope, i.e.:

    [OperationBehavior(TransactionScopeRequired = true)]
    public void MyServiceOperation(){ ... }
    
    //or using the TransactionScope
    
    public void MyServiceOperation()
    {
        using(var transScope = new TransactionScope(...)){ ... }
    }
    
  2. For retry functionality, it looks like you need to enable the ReceiveContext, following this blog:

    [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("...");
        }
    }
    

UPDATE:

After digging a little deeper, I've found that the OperationContext` completion isn't really an option if you're using plain vanilla, contract-first, IIS-hosted, WCF with Service Bus 1.0 (not sure why, but I'm hoping someone could shed some light on this)

What I have found is about the only sane option for transactional behavior is the following:

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

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

The problem remains that this pattern, unlike say MSMQ, does not allow for the entire operation to be rolled-back if sending the message to the service bus fails. (unless of course, someone out there knows better...)

This also means you're forced to roll-your-own retry logic and likely some mechanism to verify at the next step that the previous step was committed. YUCK!

From what I understand, Workflow Services and dealing directly with brokered messages gives you some out-of-the-box retry capabilities. But if you're IIS-hosting your Workflow Services with IIS via AppFabric, then somehow Microsoft figured out how to get the transaction to cover sending to the Service Bus. (If anyone knows what that mechanism is, please let me know!)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!