MsmqException (0xC00E0051) через 60 секунд
Я использую netMsmqBinding с транзакционной очередью, и хотя служба WCF вызывается без проблем, она генерирует исключение MsmqException через 60 секунд после обработки сообщения.
Это исключение:
System.ServiceModel.MsmqException (0xC00E0051): Произошла ошибка при получении сообщения из очереди: Нераспознанная ошибка -1072824239 (0xc00e0051). Убедитесь, что MSMQ установлен и работает. Убедитесь, что очередь доступна для получения. в System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(тайм-аут TimeSpan, сообщение и сообщение) в System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(тайм-аут TimeSpan, RequestContext& requestContext) в System.ServiceModelxtReContainReventRetateState)
Я провел некоторое исследование, отладку и трассировку и обнаружил, что при получении нового сообщения открываются две транзакции, первая фиксируется сразу после выполнения службы, но вторая никогда не фиксируется, поэтому после 60 секунд DTC прерывает его, выдавая MsmqException. Это определение операции:
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SomeOperation(SomeParameter parameter)
{
// business logic
}
Любые идеи о том, что происходит, и как я могу решить эту проблему?
ОБНОВИТЬ:
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>
Внедрение сервиса:
[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
}
}
Контракты на обслуживание:
[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);
}
Полное поведение:
- Клиент отправляет сообщение
- Сервис активирован
- DTC запускает две транзакции (я вижу их в мониторе DTC и в событии TransactionManager.DistributedTransactionStarted)
- Первая транзакция заканчивается, как только операция заканчивается
- Вторая транзакция прерывается через 60 секунд (генерируется MsmqException)
- Иногда происходит сбой хоста wcf (IIS) (у меня есть код для его автоматического восстановления, очевидно, это поведение изменилось в.net 4)
- Если хост был сломан и автоматически восстановлен, все произойдет снова при следующем сообщении
- Если хост не был сломан, вторая транзакция не запустится в следующий раз, и все будет работать без проблем:).
- Если я перезапускаю AppPool, проблема начинается снова
1 ответ
Я нашел проблему.
Поскольку я предоставляю одну и ту же Службу с использованием двух разных конечных точек msmq, по какой-то странной причине процесс SMSvcHost.exe дважды активирует одну и ту же конечную точку.
Я только что написал пост с решением: http://blog.jorgef.net/2011/07/msmqexception.html
Я надеюсь, что это помогает.
Jorge