简体   繁体   English

使用netMsmqBinding对WCF通道进行故障处理

[英]Faulting a WCF channel using netMsmqBinding

I have a WCF service over netMsmqBinding (MSMQ3). 我在netMsmqBinding(MSMQ3)上有WCF服务。 The service code doesn't run run under WCF transaction control because some operations in the service do not have transactional capability and are not capable of rolling back. 该服务代码不会在WCF事务控制下运行,因为该服务中的某些操作不具有事务处理能力并且无法回滚。 As I understand it, this means I do not get any of the benefits of poison message handling etc. So once my service code is invoked, the message is off the queue forever. 据我了解,这意味着我没有获得任何有害消息处理等好处。因此,一旦调用我的服务代码,该消息将永远不在队列中。

In the case of a critical failure in my service, I want to prevent further message loss. 如果我的服务严重失败,我想防止进一步的消息丢失。 So I log the message that has just failed and then raise a plain exception (not FaultException). 因此,我记录了刚刚失败的消息,然后引发一个普通异常(不是FaultException)。 As with any other WCF service binding, I expect this to fault the channel (MSMQ channel dispatcher in this case) and receive no further messages from the queue. 与任何其他WCF服务绑定一样,我希望这会使通道(在这种情况下为MSMQ通道调度程序)出现故障,并且不会从队列中接收到其他消息。

But I can't seem to get this behaviour (no pun) to work. 但是我似乎无法使这种行为(无双关)起作用。 Irrespective of whether my service code throws exceptions, I keep on getting the messages routed to the service. 无论我的服务代码是否引发异常,我都会继续将消息路由到该服务。

Am I missing something here? 我在这里想念什么吗? Does netMsmqBinding behave like the http bindings in that a new channel is created for every request? netMsmqBinding的行为是否像http绑定那样,为每个请求创建一个新通道? If so, then any idea on how to resolve my problem would be appreciated. 如果是这样,那么关于如何解决我的问题的任何想法将不胜感激。

The service code doesn't run under WCF transaction control because some operations in the service do not have transactional capability and are not capable of rolling back. 该服务代码不在WCF事务控制下运行,因为该服务中的某些操作不具有事务处理能力且无法回滚。 As I understand it, this means I do not get any of the benefits of poison message handling etc. 据我了解,这意味着我没有获得任何有害消息处理等好处。

Transactional control is in someways down to you. 事务控制在某种程度上取决于您。 Wrap a TransactionScope around the code you want to be transactional. TransactionScope包裹在您要进行交易的代码周围。 This way it is guaranteed to be transactional. 这样可以保证它是事务性的。 If you implement custom code, this is a property on the queue. 如果实现自定义代码,则这是队列上的属性。 Or, you can enable transactions on MSMQ by each queue individually. 或者,您可以按每个队列分别在MSMQ上启用事务。

The poison queue is not automatic, but in fact a seperate queue altogether. 中毒队列不是自动的,而是实际上是一个单独的队列。 You write to it when you have detected a message that is invalid and you write to it. 当您检测到无效消息并对其进行写入时,可以对其进行写入。

So I log the message that has just failed and then raise a plain exception (not FaultException). 因此,我记录了刚刚失败的消息,然后引发一个普通异常(不是FaultException)。

Raising exceptions when receiving from MSMQ doesn't work. 从MSMQ接收时引发异常不起作用。 It has nothing to throw the exception to. 它没有什么可抛出异常的。 This is where the poison queue comes into play. 这就是毒药队列发挥作用的地方。 You write to the poison queue to indicate an error has occurred. 您写入中毒队列以指示已发生错误。

Am I missing something here? 我在这里想念什么吗? Does netMsmqBinding behave like the http bindings in that a new channel is created for every request? netMsmqBinding的行为是否像http绑定那样,为每个请求创建一个新通道?

The netMsmqBinding does generate a new thread for each message being read on the server side, but writing to a MSMQ does not. netMsmqBinding确实会为服务器端读取的每条消息生成一个新线程,但不会写入MSMQ。 Each channel generates an individual thread. 每个通道生成一个单独的线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM