I am using the netMsmqBinding with a transactional queue, and although the WCF service is called without problems, the service is throwing a MsmqException just 60 seconds after the message is processed.
This is the exception:
System.ServiceModel.MsmqException (0xC00E0051): An error occurred while receiving a message from the queue: Unrecognized error -1072824239 (0xc00e0051). Ensure that MSMQ is installed and running. Make sure the queue is available to receive from. at System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(TimeSpan timeout, Message& message) at System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(TimeSpan timeout, RequestContext& requestContext) at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(TimeSpan timeout, RequestContext& requestContext)
I have done some research, debugging and tracing and I have found that when a new message is received, two transactions are opened, the first one is committed just after the service execution, but the second one is never committed, so then, after 60 seconds, the DTC aborts it throwing the MsmqException. This is the operation definition:
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SomeOperation(SomeParameter parameter)
{
// business logic
}
Any ideas about what is happening, and how can I solve this issue?
UPDATE:
Config:
<netMsmqBinding>
<binding name="TransactionalMsmqBinding" exactlyOnce="true" deadLetterQueue="System" receiveErrorHandling="Move">
<security mode="None"/>
</binding>
</netMsmqBinding>
...
<service name="SomeNamespace.SomeService">
<endpoint contract="SomeNamespace.ISomeService" bindingConfiguration="TransactionalMsmqBinding" binding="netMsmqBinding" address="net.msmq://localhost/private/services/someservice.svc">
</endpoint>
<endpoint contract="SomeNamespace.IAnotherService" bindingConfiguration="TransactionalMsmqBinding" binding="netMsmqBinding" address="net.msmq://localhost/private/services/anotherservice.svc">
</endpoint>
</service>
Service Implementation:
[ExceptionShieldingBehavior(typeof(ArgumentValidationException), typeof(ValidationServiceException))]
[AuthorizationAndAuditBehaviour]
[ServiceBehavior(Namespace = GlobalConstants.ServiceContractNamespace)]
public class SomeService: ISomeService, IAnotherService
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SomeOperation(SomeParameter parameter)
{
// business logic
}
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void AnotherOperation(AnotherParameter parameter)
{
// business logic
}
}
Service Contracts:
[ServiceContract(Namespace = GlobalConstants.ServiceContractNamespace)]
public interface ISomeService
{
[OperationContract(IsOneWay = true)]
void SomeOperation(SomeParameter parameter);
}
[ServiceContract(Namespace = GlobalConstants.ServiceContractNamespace)]
public interface IAnotherService
{
[OperationContract(IsOneWay = true)]
void AnotherOperation(AnotherParameter parameter);
}
Complete behavior:
- The client sends a message
- The service is activated
- The DTC starts two transactions (I can see them in the DTC monitor and in the TransactionManager.DistributedTransactionStarted event)
- The first transaction finishes as soon as the operation finishes
- The second transaction is aborted 60 seconds after (MsmqException is thrown)
- The wcf host (IIS) is sometimes faulted (I have some code to automatically recover it, apparently this behaviour has changed in .net 4)
- If the host was broken and automatically recovered, all will happen again on next message
- If the host was not broken, the second transaction won't start the next time and everything will work without problems :).
- If I recycle the AppPool, the problem starts again