views:

436

answers:

2

I have a WCF logging service that runs operates over MSMQ. Items are logged to a Sql Server 2005 database. Every functions correctly if used outside a TransactionScope. When used inside a TransactionScope instance the call always causes the transaction to be aborted. Message = "The transaction has aborted".

What do I need to do to get this call to work inside a Transaction? Is it even possible. I've read that for a client transaction to flow across a service boundary the binding must support transaction flow, which immediately limits the bindings to only NetNamedPipeBinding, NetTcpBinding, WSHttpBinding, WSDualHttpBinding and WSFederationHttpBinding.

+2  A: 

Sorry for the needless question...

I have solved my problem. I needed to place [TransactionFlow(TransactionFlowOption.Allowed)] on the operation in the service contract and then [OperationBehavior(TransactionScopeRequired=true)] on the implementation of the contract (the service itself).

Works a treat.

rob_g
you beat me by seconds! :-)
marc_s
posted my reply anyway, since it contains a good link to a blog post series by Tom Hollander on WCF and MSMQ - excellent read!
marc_s
+2  A: 

I'm not intimately knowledgeable about MSMQ, but there's a really good blog post series by Tom Hollander on MSMQ, IIS and WCF: Getting them to play nicely - in part 3 which is the link provided Tom talks about getting transactional.

MSMQ can be transactional - or not. And in WCF, you can decorate both the service contract as well as individual operation contracts (methods) with transaction-related attributes, such as whether to allow, disallow, or require a transaction context.

As far as I understand, in your setup, you don't want the MSMQ part to be transactional - but you should be able to use it even if an ambient transaction is present. In this case, you need to add the TransactionFlow="ALlowed" to your operation contract like this:

[ServiceContract]
public interface ILoggingService
{
  [OperationContract]
  [TransactionFlow(TransactionFlowOption.Allowed)]
  void LogData(......);
}

That should do it!

Marc

marc_s
thanks marc. you're correct. I don't want the transaction behavior (especially as one of the services is an email sending service). I'll try that attribute.
rob_g