MSDTC escalation issue when using EF in an Orchard Module

Topics: Troubleshooting, Writing modules
Jun 12, 2012 at 12:49 PM

I know, this is not a recommended practice of working with a Database in an Orchard Module, but I have a legacy application written in ASP.NET MVC and EntityFramework that needs to be converted to an Orchard module. Re-writing the DAL would be too much of work, so I am trying to make EF code to work. And most of the time it works.

However, in some situations, I am getting MSDTC escallation and error "MSDTC is not available". And it happens after a set of successful EF operations. If I am authenticated in Orchard, the error happens almost for sure. For unauthenticated scenario, some operations work fine, others give an error. Also, any attempt to call a method that is accessing DB from View, automatically results in MSDTC error.

If anyone has been in a similar situation, I would appreciate any hint as to how to resolve it.

Thank you.


Jun 12, 2012 at 2:08 PM

Is the DTC service running?

Jun 12, 2012 at 3:55 PM
Edited Jun 12, 2012 at 3:56 PM

Yes, DTC service is running, so it seems strange to me that the error is saying MSDTC is not available. However, from what I read, MSDTC is causing unnecessary overhead and it is recommended to avoid using it. So I did not try to find out why the system does not see a running MSDTC, and instead I am trying to fix the code so that it does not escalate to MSDTC at all.

I understand the error happens because of two overlapping connections to database within a single TransactionScope - one from Orchard itself through NHibernate, and another from my module via EF. Orchard opens a TransactionScope at the beginning of each request, so my DB access is falling within the range of that TransactionScope. If I could somehow wrap my DB code within my own TransactionScope, that would most probably fix the problem. But I believe they cannot be nested.

Jun 13, 2012 at 4:43 AM

Put this around your EF code:

using (var scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Suppress)) {}
Jun 13, 2012 at 1:48 PM

Thank you! Having internal TransactionScope with Suppress solved the problem.