1

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.

Rob Gray
  • 3,186
  • 4
  • 33
  • 34

2 Answers2

4

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

Community
  • 1
  • 1
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 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 Gray Oct 06 '09 at 22:50
2

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.

Serve Laurijssen
  • 9,266
  • 5
  • 45
  • 98
Rob Gray
  • 3,186
  • 4
  • 33
  • 34
  • 1
    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 Oct 06 '09 at 08:22