2009-05-26 10 views
7

In meiner Webanwendung muss ich die Benutzeraktionen überwachen. Wenn der Benutzer eine Aktion ausführt, aktualisiere ich das Objekt, auf dem die Aktion ausgeführt wird, und behalte den Audit-Trail dieser Aktion bei.Verwenden von Transaktionen mit Unterschall

Jetzt, wenn ich zuerst das Objekt ändern und dann Audit-Trail aktualisieren, aber der Audit-Trail fehlschlägt dann was?

Offensichtlich muss ich Änderungen an modifiziertem Objekt zurücksetzen. Ich kann Sql-Transaktionen in einfacher Anwendung verwenden, aber ich benutze Subsonic, um mit db zu sprechen. Wie kann ich mit der Situation umgehen?

Antwort

10

Etwas wie:

Using ts As New System.Transactions.TransactionScope() 
    Using sharedConnectionScope As New SubSonic.SharedDbConnectionScope() 

' Do your individual saves here 

' If all OK 
     ts.Complete() 

    End Using 
End Using 
+1

Ich kann bestätigen, dass TransactionScope korrekt mit SubSonic funktioniert, und Rollback-Transaktionen korrekt durchführt. – kd7

+0

Danke @kevinw und @bnkdev. Ich verwende C#, also poste ich den Code in C# auch, damit es von anderen leicht verwendet werden kann. Würden Sie auch nicht die einzelnen Sicherungen oder Aktionen in Versuch/Fang setzen, so ist es einfacher zu wissen, ob alles Ok oder nicht? – TheVillageIdiot

14

Die answer von @Kevinw gegeben ist vollkommen in Ordnung. Ich poste dies nur als Übersetzung seiner Antwort auf C# -Code. Ich verwende keine Kommentare, da der Code nicht formatiert wird :) Außerdem verwende ich try/catch, um zu wissen, ob die Transaktion abgeschlossen oder zurückgesetzt werden soll.

using (System.Transactions.TransactionScope ts = new TransactionScope()) 
{ 
    using (SharedDbConnectionScope scs = new SharedDbConnectionScope()) 
    { 
     try 
     { 
      //do your stuff like saving multiple objects etc. here 

      //everything should be completed nicely before you reach this 
      //line if not throw exception and don't reach to line below 
      ts.Complete(); 
     } 
     catch (Exception ex) 
     { 
      //ts.Dispose(); //Don't need this as using will take care of it. 
      //Do stuff with exception or throw it to caller 
     } 
    } 
} 
+1

Das Aufrufen von 'ts.Dispose()' in der catch-Klausel ist nicht erforderlich, da die using-Anweisung dies sowieso übernimmt. Im allgemeinen Fall könnte es sogar Probleme verursachen, da 'SharedDbConnectionScope' oder anderer transaktionsbewusster Code, der innerhalb des Transaktionsbereichs gestartet wird, davon abhängen könnte, dass er entsorgt wird, bevor der umschließende Transaktionsbereich entsorgt wird. –

+0

@OskarBorggren hat es kommentiert. – TheVillageIdiot

1

Nein. Wenn ich die SharedDbConnectionScope außerhalb der Änderungen setzen, sind in der Datenbank vor ts.Complete() sichtbar. Durch das Einsetzen wird der Server blockiert, bis die Operation abgeschlossen ist.

Verwandte Themen