2014-10-31 11 views
5

Ich bin nicht in der Lage den folgenden Code zu erhalten, die nur eine einzige Datenbank berührt einen einzelnen Kontext zu MSDTC ausführen verwenden, ohne Eskalation und ist eine Ausnahme auf context.SaveChanges werfen():Entity Framework Distributed Forcierung Transaktion

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(); 
    } 
} 

Die Ausnahme ist "Der zugrunde liegende Anbieter auf Öffnen fehlgeschlagen -> Der Partner Transaktionsmanager seine Unterstützung für Remote/Netzwerk-Transaktionen deaktiviert hat (Ausnahme von HRESULT: 0x8004D025).."

Hinweis:

    Diese
  • ist EF mit 6 und SQL Server 2005
  • Aufgrund eines DB-Server gesperrt Ich bin nicht in der Lage MSDTC zu verwenden
  • Ich möchte Transaction in der POC verwenden, da dies in WCF ausgeführt werden, die Transaction hat gebaut in und ich möchte meinen Code nicht mit Transaktionsverwaltung einstreuen.
  • ähnliche Projekte verwenden NHibernate und haben nicht dieses Problem

Verbindungszeichenfolge sind:

Connection = "Metadaten = res: // /ResourceAccess.MyDb.csdl|res:///ResourceAccess.MyDb.ssdl | res: //*/ResourceAccess.MyDb.msl; provider = System.Data.SqlClient; Anbieterverbindungszeichenfolge = " Datenquelle = wil-gvpsqldev01; initialer Katalog = MyDb; integrierte Sicherheit = True; MultipleActiveResultSets = True; App = EntityFramework " "providerName =" System.Data.EntityClient "/>

System.Transactions Diagnostik sind:

<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 
+0

Gibt es irgendwelche Trigger auf dem Tisch, vielleicht? –

+0

Wow, ich habe nicht einmal daran gedacht.Nur überprüft und es gibt keine Trigger. –

Antwort

3

Das Problem war mit EF die Verbindung zwischen bekommen die Einheiten für groupId schließen und dann die Objekte zu löschen. Dies verursachte die Eskalation. Die Arbeit um ist das Öffnen und Schließen der Verbindung zu steuern:

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

Verhalten in EF6 und zukünftige Versionen

Für EF6 und zukünftige Versionen wir den Ansatz genommen haben, dass, wenn die Berufung code wählt, um die Verbindung zu öffnen, indem context.Database.Connection.Open() aufrufen, dann hat es einen guten Grund dafür so zu tun, und das Framework wird davon ausgehen, dass es Kontrolle über das Öffnen und das Schließen der Verbindung will und nicht mehr Schließen Sie die Verbindung automatisch .

Die einzige Dokumentation dieses Verhalten I ist die Tabelle in diesem Blog-Eintrag finden konnten, die das 2008 vor der Versionen von SQL Server impliziert wird eskalieren, wenn es mehrere Verbindungen sind:

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

Hier ist wo ich landete:

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(); 
       } 
      } 
     } 
    } 
} 
+1

Ich habe dieses Verhalten von EF noch nie gesehen, weil MSDTC eintrat. Es sollte vollkommen möglich sein, die Verbindung mehrmals innerhalb eines "TransactionScope" zu öffnen und zu schließen. Aber eine andere Frage: Warum TransactionScope verwenden, wenn nur ein SaveChanges-Aufruf vorliegt? –

+0

@GertArnold Gute Frage. In Bezug auf TS wird dieser Code letztendlich in WCF leben, das TS verwendet, wenn Sie die integrierte Tx-Verwaltung verwenden. Sobald ich das funktionierte, habe ich den TS aus dieser Methode in eine Aufrufmethode verschoben und eine andere Methode mit einem anderen SaveChanges aufgerufen. Wenn ich auf ein Problem stoße, versuche ich es so weit wie möglich zu vereinfachen, um an die Ursache zu gelangen, und der obige Code war der einfachste, den ich bekommen konnte, während ich immer noch scheiterte. Ich werde die Antwort zu Ihrer ersten Frage aktualisieren. –