2015-03-03 6 views
5

In meiner Anwendung habe ich Methode sieht wie folgt aus:Wie verwendet man Transaktionen für verschiedene Kontexte?

public static bool DoLargeOperation() 
{ 
    bool res = true; 

    res = res && DoFirstSubOperation(); 
    res = res && DoSecondSubOperation(); 
    res = res && DoThirdSubOperation(); 

    return res; 
} 

Und jeder der internen Verfahren sieht wie folgt aus:

public static bool DoFirstSubOperation() 
{ 
    using (var context = new EntityFrameworkContext()) 
    { 
     // data modification. 
     context.SaveChanges(); 
    } 
} 

Zum Beispiel DoFirstSubOperation() und DoSecondSubOperation() erfolgreich abgeschlossen, aber DoThirdSubOperation() ausfällt. Wie rolle ich die Änderungen der ersten beiden Funktionen zurück?

Dieser Ansatz hat nicht gebracht Ergebnisse:

using (var transaction = new TransactionScope()) 
{ 
    res = res && DoFirstSubOperation(); 
    res = res && DoSecondSubOperation(); 
    res = res && DoThirdSubOperation(); 
} 

Die einzige Lösung, die ich sehe, ist der Kontext wie so zu definieren:

public static bool DoLargeOperation() 
{ 
    bool res = true; 

    using (var context = new EntityFrameworkContext()) 
    { 
     using (var transaction = context.Database.BeginTransaction()) 
     { 

      res = res && DoFirstSubOperation(context); 
      res = res && DoSecondSubOperation(context); 
      res = res && DoThirdSubOperation(context); 
      if (res) 
      { 
       transaction.Commit(); 
      } 
      else 
      { 
       transaction.Rollback(); 
      } 
     } 
    } 

    return res; 
} 

Aber ist es akzeptabel, dies zu tun? Oder gibt es eine andere Lösung?

+0

Was hat in diesem Ansatz nicht funktioniert? Es ist der richtige Weg, um das zu erreichen, wonach Sie suchen. – abatishchev

+0

Es werden keine Änderungen in abgeschlossenen Operationen rückgängig gemacht. –

+0

Ohne 'scope.Commit()' sollte es sie eigentlich nicht begehen. Wie überprüfen Sie die Änderungen? Vielleicht sind Sie in derselben Transaktion? Oder extern, sagen wir mal Management Studio? – abatishchev

Antwort

5

Ja, das ist das richtige Muster. Wenn der Kontext an die Methoden übergeben wird, können die Methoden an mehreren Speicherorten wiederverwendet werden, da der Kontext und die Transaktion vom Aufrufer verwaltet werden.

Sie werden die Verarbeitung der nachfolgenden Methoden wahrscheinlich nicht fortsetzen, wenn die erste fehlschlägt. Sie wollen wahrscheinlich auch das Gespräch mit den Kindern in einem try/catch wickeln, so dass jede Ausnahme der Rollback korrekt auftreten können ...

try 
{ 
    res = DoFirstSubOperation(context); 
    if (res) 
     res = DoSecondSubOperation(context); 
    if (res) 
     res = DoThirdSubOperation(context);  

    if (res) 
     transaction.Commit(); 
    else 
     transaction.Rollback(); 
} 
catch 
{ 
    transaction.Rollback(); 
} 

Wenn Ihr Kind Methoden bereits Ausnahmen behandeln, dann können Sie den Versuch verzichten/Fang.

+0

Vielen Dank! Ich vereinfache nur Beispiel, um nur die Essenz zu zeigen. –

Verwandte Themen