5 Stimmen

Wie hängt die Rückgängigmachung von Transaktionen mit LINQ to SQL zusammen?

Die Frage bezieht sich ausschließlich auf die Rückgängigmachung der Änderungen, nicht auf das Commit.

Angenommen, ich rufe einige Daten ab, ändere sie, übermittle die Änderungen (optionaler Schritt) und führe die Transaktion zurück. Wo auch immer Sie hinschauen, jeder Autor schreibt, dass dies die Änderungen rückgängig macht.

Aber ich habe herausgefunden, dass das nur halb wahr ist - LINQ DataContext behält die geänderten Daten! Ich habe dies mit TransactionScope und DataContext.Transaction getestet. In beiden Fällen erhielt ich das gleiche Verhalten.

Eine Abhilfe wäre, den DataContext nach dem Rollback neu zu erstellen (dies führt jedoch zu anderen Problemen wie der Zwischenspeicherung von Daten und der Handhabung verschachtelter Transaktionen) oder die Änderungen im DataContext manuell zu verwerfen. Dies sind jedoch nur Behelfslösungen.

Fragen

Was vermisse ich also? Ist LINQ to SQL nicht für Transaktionen geeignet? Wie kann man Transaktionen so verwenden, dass sie WIRKLICH Änderungen rückgängig machen?

Beispiel

                MyTable record = null;

                db.Connection.Open();
                using (db.Transaction = db.Connection.BeginTransaction())
                {
                        record = db.MyTable.First();
                        record.BoolField = !record.BoolField; // changed
                        db.SubmitChanges();
                        db.Transaction.Rollback();
                }

4voto

Marc Gravell Punkte 970173

Ein Datenkontext sollte als eine Arbeitseinheit betrachtet werden. Wie körnig Das kann eine Seitenanforderung oder eine einzelne Operation sein, aber wenn Sie eine Ausnahme (oder so ziemlich alles Unerwartete) erhalten, - stoppen den Datenkontext aufgeben und ein Rollback durchführen. Nach einem Rollback wird Ihr Datenkontext verwirrt sein, also einfach behalte es nicht .

Außerdem sollten Sie einen Datenkontext nicht länger als nötig aufbewahren. Er ist nicht als App-langer Daten-Cache gedacht.

2voto

tvanfosson Punkte 506878

Was Sie zu fragen scheinen, ist ein In-Memory-Cache der Datenbank (oder ein Teil davon) eher als eine leichtgewichtige ORM. Ich würde sagen, dass LINQ to SQL für Transaktionen und als leichtgewichtiges ORM gut geeignet ist, aber nicht so gut, um es sofort als Datenbank-Cache zu verwenden. Der Datenkontext funktioniert meiner Meinung nach am besten, wenn man das Unit of Work-Muster verwendet. Erstellen Sie den Kontext für eine bestimmte Aufgabe, führen Sie die Aufgabe aus und entsorgen Sie dann den Kontext. Wenn die Aufgabe zufällig eine fehlgeschlagene Transaktion enthält, müssen Sie herausfinden, wie Sie auf den Fehler reagieren können. Dies kann entweder durch eine Fehlerkorrektur und einen erneuten Versuch mit dem vorhandenen Kontext geschehen oder, wie bei einem Web-Kontext, durch die Rückgabe der versuchten Änderungen an den Benutzer und einen erneuten Versuch mit einem neuen Kontext, wenn die Daten erneut übermittelt werden.

0voto

Pleun Punkte 8836

Zwei Dinge:

1) veralteter Datenkontext

Was Sie beobachten, wird gemeinhin als "veralteter" Datenkontext bezeichnet. Die Entitäten im Datentext bemerken Ihren Rollbak nicht. Sie würden ein ähnliches Verhalten erhalten, wenn Sie eine gespeicherte Prozedur nach Ihren Submitchanges ausführen würden. Auch dies wird vom Datentext nicht bemerkt. Allerdings werden Ihre Transaktionen in der DB zurückgerollt! (und die Stored Procedure wird ebenfalls ausgeführt)

2) über Transaktionen

Es besteht keine Notwendigkeit, die Transaktion zu verwalten. Linq2Sql erstellt bereits eine Transaktion für Sie in der Submitchanges. Wenn Sie die Transaktionen wirklich verwalten wollen (z.B. über mehrere Datenkontexte oder eine gespeicherte Prozedur kombiniert mit etwas Linq2Sql), verpacken Sie das Ganze in ein TransactionScope. Rufen Sie transaction.Complete() an dem Punkt auf, an dem Sie eine Übergabe durchführen wollen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X