Ich habe untersucht worden Transaktionen und es scheint , dass sie sich selbst in EF kümmern, solange ich pass false
auf SaveChanges()
und rufen Sie dann , AcceptAllChanges()
wenn es keine Fehler sind:
SaveChanges(false);
// ...
AcceptAllChanges();
Was ist, wenn etwas schief geht? Muss ich kein Rollback durchführen oder ist die Transaktion beendet, sobald meine Methode den Gültigkeitsbereich verlässt?
Was passiert mit Einrückungsspalten, die nach der Hälfte der Transaktion zugewiesen wurden? Ich nehme an, wenn jemand anderes einen Datensatz nach meinem hinzugefügt hat, bevor meiner schlecht wurde, bedeutet dies, dass ein Identitätswert fehlt.
Gibt es einen Grund, die Standardklasse TransactionScope
in meinem Code zu verwenden?
c#
entity-framework
transactions
Mark Smith
quelle
quelle
SaveChanges(fase); ... AcceptAllChanges();
es überhaupt ein Muster gab. Beachten Sie, wie die akzeptierte Antwort auf die obige Frage vom Autor eines Blogs geschrieben wird - und auf dieses Blog wird in der anderen Frage verwiesen. Es kommt alles zusammen.Antworten:
Mit dem Entity Framework ist die meiste Zeit
SaveChanges()
ausreichend. Dadurch wird eine Transaktion erstellt oder eine Umgebungstransaktion eingetragen, und alle erforderlichen Arbeiten für diese Transaktion werden ausgeführt.Manchmal ist die
SaveChanges(false) + AcceptAllChanges()
Paarung jedoch nützlich.Der nützlichste Ort hierfür ist in Situationen, in denen Sie eine verteilte Transaktion über zwei verschiedene Kontexte ausführen möchten.
Dh so etwas (schlecht):
Wenn dies
context1.SaveChanges()
erfolgreich ist, abercontext2.SaveChanges()
fehlschlägt, wird die gesamte verteilte Transaktion abgebrochen. Leider hat das Entity Framework die Änderungen bereits verworfencontext1
, sodass Sie den Fehler nicht wiederholen oder effektiv protokollieren können.Aber wenn Sie Ihren Code so ändern, dass er so aussieht:
Während der Aufruf zum
SaveChanges(false)
Senden der erforderlichen Befehle an die Datenbank wird der Kontext selbst nicht geändert, sodass Sie ihn bei Bedarf erneut ausführen oder bei Bedarf abfragen könnenObjectStateManager
.Dies bedeutet, wenn die Transaktion tatsächlich eine Ausnahme auslöst, können Sie diese kompensieren, indem Sie den Status jedes Kontexts entweder erneut versuchen oder protokollieren
ObjectStateManager
.Weitere Informationen finden Sie in meinem Blogbeitrag .
quelle
SaveChanges(false)
führt die eigentliche Aktualisierung der Datenbank durch undAcceptAllChanges()
teilt EF mit: "Okay, Sie können vergessen, welche Dinge gespeichert werden müssen, da sie erfolgreich gespeichert wurden." Wenn diesSaveChanges(false)
fehlschlägt,AcceptAllChanges()
wird es niemals aufgerufen, und EF betrachtet Ihr Objekt weiterhin als Eigenschaften, die geändert wurden und in der Datenbank gespeichert werden müssen.Wenn Sie EF6 (Entity Framework 6+) verwenden, hat sich dies für Datenbankaufrufe an SQL geändert.
Siehe: http://msdn.microsoft.com/en-us/data/dn456843.aspx
Verwenden Sie context.Database.BeginTransaction.
Von MSDN:
quelle
throw;
zum MSDN-Snippet hinzugefügt und klar angegeben, dass es nicht das Original aus dem MSDN-Artikel ist.Rollback()
unabhängig davon sein soll, mit welcher Datenbank es spricht, wird es aufgerufen, falls es mit MySQL spricht oder etwas, das dieses automatische Verhalten nicht aufweist.Da einige Datenbanken bei dbContextTransaction.Commit () eine Ausnahme auslösen können, ist dies besser:
quelle
false
incontext.SaveChanges();
und zusätzlich nennencontext.AcceptAllChanges();
.