Entity Framework Forces Transaction Distribution

I cannot get the following code that only applies to one database, using a single context to run without raising to MSDTC, and throwing an exception in context.SaveChanges ():

public void DeleteGroupDetails(int groupId) { // Note there is no ambient tx var thisIsNull = Transaction.Current; using (var scope = new TransactionScope()) { var thisIsNotNull = Transaction.Current; using (var context = new MyDbEntities()) { var deleted = context.tblGroups.Where(x => x.GroupID == groupId); context.tblGroups.RemoveRange(deleted); try { context.SaveChanges(); } catch (Exception e) { Console.WriteLine(e); } } //scope.Complete(); } } 

An exception is the "Failure of the primary provider to open." > The partner's transaction manager has disabled remote / network transaction support. (Exception from HRESULT: 0x8004D025) "

Note:

  • This is using EF 6 and SQL Server 2005
  • Due to a blocked db server I cannot use MSDTC
  • I want to use TransactionScope in POC because it will work in the WCF that TransactionScope is built into, and I do not want my code to handle the transaction.
  • Similar projects use NHibernate and do not have this problem.

Connection string:

ConnectionString = "metadata = Res: ///ResourceAccess.MyDb.csdl | Res: ///ResourceAccess.MyDb.ssdl | Res: //*/ResourceAccess.MyDb.msl; provider = System.Data.SqlClient; provider connection string = "data source = wil-gvpsqldev01; start directory = MyDb; integrated security = True; MultipleActiveResultSets = True; App = EntityFramework "" providerName = "System.Data.EntityClient" / ">

Diagnostics System.Transactions:

 <E2ETraceEvent> <System> <EventID>0</EventID> <Type>3</Type> <SubType Name="Information">0</SubType> <Level>8</Level> <TimeCreated SystemTime="2014-10-31T14:39:43.0061489Z" /> <Source Name="System.Transactions" /> <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /> <Execution ProcessName="CCS.Host.Console.vshost" ProcessID="64568" ThreadID="13"/> <Channel/> <Computer>xxx</Computer> </System> <ApplicationData> <TraceData> <DataItem> <TraceRecord Severity="Information"> <TraceIdentifier>http://msdn.microsoft.com/2004/06/System/Transactions/TransactionCreate</TraceIdentifier> <Description>Transaction Created</Description> <AppDomain>CCS.Host.Console.vshost.exe</AppDomain> <ExtendedData> <TraceSource>[Lightweight]</TraceSource> <TransactionTraceIdentifier> <TransactionIdentifier>2e0814b3-7dd2-4c05-ad69-c3787d95c208:1</TransactionIdentifier> <CloneIdentifier>1</CloneIdentifier> </TransactionTraceIdentifier> </ExtendedData> </TraceRecord> </DataItem> </TraceData> </ApplicationData> </E2ETraceEvent> <E2ETraceEvent> <System> <EventID>0</EventID> <Type>3</Type> <SubType Name="Information">0</SubType> <Level>8</Level> <TimeCreated SystemTime="2014-10-31T14:39:43.0181489Z" /> <Source Name="System.Transactions" /> <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /> <Execution ProcessName="CCS.Host.Console.vshost" ProcessID="64568" ThreadID="13"/> <Channel/> <Computer>xxx</Computer> </System> <ApplicationData> <TraceData> <DataItem> <TraceRecord Severity="Information"> <TraceIdentifier>http://msdn.microsoft.com/2004/06/System/Transactions/TransactionScopeCreated</TraceIdentifier> <Description>TransactionScope Created</Description> <AppDomain>CCS.Host.Console.vshost.exe</AppDomain> <ExtendedData> <TraceSource>[Base]</TraceSource> <TransactionTraceIdentifier> <TransactionIdentifier>2e0814b3-7dd2-4c05-ad69-c3787d95c208:1</TransactionIdentifier> <CloneIdentifier>2</CloneIdentifier> </TransactionTraceIdentifier> <TransactionScopeResult>CreatedTransaction</TransactionScopeResult> </ExtendedData> </TraceRecord> </DataItem> </TraceData> </ApplicationData> </E2ETraceEvent> <E2ETraceEvent> <System> <EventID>0</EventID> <Type>3</Type> <SubType Name="Information">0</SubType> <Level>8</Level> <TimeCreated SystemTime="2014-10-31T14:39:49.1921489Z"/> <Source Name="System.Transactions"/> <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}"/> <Execution ProcessName="CCS.Host.Console.vshost" ProcessID="64568" ThreadID="13"/> <Channel/> <Computer>ccc</Computer> </System> <ApplicationData> <TraceData> <DataItem> <TraceRecord Severity="Information"> <TraceIdentifier>http://msdn.microsoft.com/2004/06/System/Transactions/Enlistment</TraceIdentifier> <Description>Enlistment Created</Description> <AppDomain>CCS.Host.Console.vshost.exe</AppDomain> <ExtendedData> <TraceSource>[Lightweight]</TraceSource> <EnlistmentTraceIdentifier> <ResourceManagerId>00000000-0000-0000-0000-000000000000</ResourceManagerId> <TransactionTraceIdentifier> <TransactionIdentifier>2e0814b3-7dd2-4c05-ad69-c3787d95c208:1</TransactionIdentifier> <CloneIdentifier>2</CloneIdentifier> </TransactionTraceIdentifier> <EnlistmentIdentifier>0</EnlistmentIdentifier> </EnlistmentTraceIdentifier> <EnlistmentType>PromotableSinglePhase</EnlistmentType> <EnlistmentOptions>None</EnlistmentOptions> </ExtendedData> </TraceRecord> </DataItem> </TraceData> </ApplicationData> </E2ETraceEvent> <E2ETraceEvent > <System > <EventID>0</EventID> <Type>3</Type> <SubType Name="Error">0</SubType> <Level>2</Level> <TimeCreated SystemTime="2014-10-31T14:39:50.8941489Z" /> <Source Name="System.Transactions" /> <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /> <Execution ProcessName="CCS.Host.Console.vshost" ProcessID="64568" ThreadID="13" /> <Channel/> <Computer>ccc</Computer> </System> <ApplicationData> <TraceData> <DataItem> <TraceRecord Severity="Error"> <TraceIdentifier>http://msdn.microsoft.com/2004/06/System/Transactions/TransactionException</TraceIdentifier> <Description>TransactionException Thrown</Description> <AppDomain>CCS.Host.Console.vshost.exe</AppDomain> <ExtendedData xmlns="http://schemas.microsoft.com/2004/03/Transactions/TransactionExceptionTraceRecord"> <TraceSource>[Distributed]</TraceSource> <ExceptionMessage>The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)</ExceptionMessage> </ExtendedData> </TraceRecord> </DataItem> </TraceData> </ApplicationData> </E2ETraceEvent> <E2ETraceEvent > <System > <EventID>0</EventID> <Type>3</Type> <SubType Name="Warning">0</SubType> <Level>4</Level> <TimeCreated SystemTime="2014-10-31T14:39:50.9591489Z" /> <Source Name="System.Transactions" /> <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /> <Execution ProcessName="CCS.Host.Console.vshost" ProcessID="64568" ThreadID="13" /> <Channel/> <Computer>ccc</Computer> </System> <ApplicationData> <TraceData> <DataItem> <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Warning"> <TraceIdentifier>http://msdn.microsoft.com/2004/06/System/Transactions/EnlistmentCallbackNegative</TraceIdentifier> <Description>Enlistment Callback Negative</Description> <AppDomain>CCS.Host.Console.vshost.exe</AppDomain> <ExtendedData > <TraceSource>[Lightweight]</TraceSource> <EnlistmentTraceIdentifier> <ResourceManagerId>00000000-0000-0000-0000-000000000000</ResourceManagerId> <TransactionTraceIdentifier> <TransactionIdentifier>2e0814b3-7dd2-4c05-ad69-c3787d95c208:1</TransactionIdentifier> <CloneIdentifier>2</CloneIdentifier> </TransactionTraceIdentifier> <EnlistmentIdentifier>0</EnlistmentIdentifier> </EnlistmentTraceIdentifier><EnlistmentCallback>Aborted</EnlistmentCallback> </ExtendedData> </TraceRecord> </DataItem> </TraceData> </ApplicationData> </E2ETraceEvent> <E2ETraceEvent > <System > <EventID>0</EventID> <Type>3</Type> <SubType Name="Warning">0</SubType> <Level>4</Level> <TimeCreated SystemTime="2014-10-31T14:39:50.9601489Z" /> <Source Name="System.Transactions" /> <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /> <Execution ProcessName="CCS.Host.Console.vshost" ProcessID="64568" ThreadID="13" /> <Channel/> <Computer>ccc</Computer> </System> <ApplicationData> <TraceData> <DataItem> <TraceRecord Severity="Warning"> <TraceIdentifier>http://msdn.microsoft.com/2004/06/System/Transactions/TransactionAborted</TraceIdentifier> <Description>Transaction Aborted</Description> <AppDomain>CCS.Host.Console.vshost.exe</AppDomain> <ExtendedData > <TraceSource>[Lightweight]</TraceSource> <TransactionTraceIdentifier> <TransactionIdentifier>2e0814b3-7dd2-4c05-ad69-c3787d95c208:1</TransactionIdentifier> </TransactionTraceIdentifier> </ExtendedData> </TraceRecord> </DataIt 
+5
source share
1 answer

The problem was that EF closes the connection between getting the objects for groupId and then removes the entities. This caused an escalation. The job is to control the opening and closing of the connection:

http://msdn.microsoft.com/en-us/data/dn456849.aspx

Behavior in EF6 and Future Versions

For EF6 and future versions, we used an approach that, if the call code selects to open a connection by calling context.Database.Connection.Open (), then this has a good reason for execution, therefore the structure assumes that it wants to control the opening and closing the connection and will no longer close the connection automatically.

The only documentation on this behavior that I could find is the table in this blog post, which implies that versions of SQL Server until 2008 will escalate if there are multiple connections:

https://petermeinl.wordpress.com/2011/03/13/avoiding-unwanted-escalation-to-distributed-transactions/

This is where I landed:

 using System; using System.Data; namespace Services.ResourceAccess { public class ResourceAccess : IDisposable { private readonly Lazy<MyDbEntities> _context; public ResourceAccess() { _context = new Lazy<MyDbEntities>(() => { var context = new MyDbEntities(); context.Database.Connection.Open(); return context; }); } public void DeleteGroupDetails(int groupId) { var deleted = _context.Value.tblGroupDetails.Where(x => x.GroupID == groupId); _context.Value.tblGroupDetails.RemoveRange(deleted); _context.Value.SaveChanges(); } public void Dispose() { if (_context.IsValueCreated) { if (_context.Value.Database.Connection.State == ConnectionState.Open) { _context.Value.Database.Connection.Close(); } } } } } 
+3
source

Source: https://habr.com/ru/post/1205982/


All Articles