Faulting a WCF channel using netMsmqBinding

324 views Asked by At

I have a WCF service over netMsmqBinding (MSMQ3). 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. 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). 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.

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? If so, then any idea on how to resolve my problem would be appreciated.

1

There are 1 answers

0
Dominic Zukiewicz On

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. 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. 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.

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).

Raising exceptions when receiving from MSMQ doesn't work. 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?

The netMsmqBinding does generate a new thread for each message being read on the server side, but writing to a MSMQ does not. Each channel generates an individual thread.