我敢肯定我不是第一个说出来的,但是对于Windows Server的服务总线1.0的细节,严重缺乏文档...我希望一些MS内部人员可以帮助澄清一些事情......
利用队列/主题的服务是否在隐式环境事务中运行?例如,请考虑以下代码段:
[ServiceBehavior]
public class MySbService : IDoWork
{
[OperationBehavior]
void DoSomeWork(WorkRequest request)
{
DoDatabaseWork();
DoMoreDatabaseWork();
}
}
在上面的示例中,如果TransactionScope
抛出异常,则在不创建显式DoDatabaseWork()
的情况下会提交DoMoreDatabaseWork()
吗?换句话说,排队操作是否在MSDTC跟踪的环境事务下运行?
如果抛出异常(如MSMQ那样),Service Bus 1.0队列会自动重试吗?我问,因为我没有遇到指定重试行为的.config
的任何netMessagingBinding
设置。此外,在使用Service Bus Explorer
创建队列时,我看到的最接近的是MaxDeliveryAttempt
。来自MSMQ背景,我习惯于在重试/毒药队列中看到异常消息。在Service Bus 1.0世界中是否存在与此同义的东西?
提前谢谢
更新
有关详细信息,请参阅下面的答案。我正在修改这个问题以询问以下内容:
是否可以使用契约优先,IIS托管的WCF和Service Bus 1.0来“覆盖”客户端在事务中发送到服务总线?如果是这样,怎么样?另外,使用的机制是什么?
答案 0 :(得分:2)
我相信我已经找到了我的两个问题的答案......
对于Transactional
操作,我不相信存在“环境”事务。我已经通过简单地在数据库操作之后抛出异常证明了这一点,果然,无论如何都会提交数据。我想知道是否有一种声明交易范围的首选方法,即:
[OperationBehavior(TransactionScopeRequired = true)]
public void MyServiceOperation(){ ... }
//or using the TransactionScope
public void MyServiceOperation()
{
using(var transScope = new TransactionScope(...)){ ... }
}
对于重试功能,您似乎需要启用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("...");
}
}
<强>更新强>
深入挖掘之后,我发现如果你使用普通的vanilla,契约优先,IIS托管的WCF和Service Bus 1.0,那么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不同,此模式不允许在将消息发送到服务总线失败时回滚整个操作。 (除非当然有人知道更好......)
这也意味着您不得不自行滚动自己的重试逻辑,并且可能需要一些机制来在下一步验证上一步是否已提交。 YUCK!
据我所知,Workflow Services和直接处理代码消息为您提供了一些开箱即用的重试功能。但是如果你通过AppFabric用IIS托管你的工作流服务,那么微软就会想出如何让交易覆盖发送到服务总线。 (如果有人知道那个机制是什么,请告诉我!)
答案 1 :(得分:0)
对于#2,您可以通过Transient Fault Handling Framework
重试http://windowsazurecat.com/2011/02/transient-fault-handling-framework/
通读本文档了解与服务总线相关的用法。