2009-05-26 17 views
7

W mojej aplikacji internetowej muszę kontrolować działania użytkowników. Tak więc, gdy użytkownik podejmuje działanie, aktualizuję obiekt, na którym podejmowana jest akcja, i utrzymuję ścieżkę audytu dla tej akcji.Korzystanie z transakcji poddźwiękowych

Teraz Jeśli najpierw zmodyfikuję obiekt, a następnie zaktualizuję ścieżkę audytu, ale ścieżka audytu nie powiedzie się, to co?

Oczywiście muszę wycofać zmiany do zmodyfikowanego obiektu. Mogę używać transakcji Sql w prostej aplikacji, ale używam Subsonic do rozmawiania z db. Jak poradzę sobie z sytuacją?

Odpowiedz

10

Coś jak:

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

Mogę potwierdzić, że TransactionScope działa poprawnie z SubSonic i wykonuje operacje wycofywania poprawnie. – kd7

+0

Dzięki @kevinw i @ bnkdev. Używam C#, więc opublikuję kod również w języku C#, aby mógł być łatwo używany przez innych. Czy nie umieściłbyś pojedynczych zapisów lub akcji w try/catch, więc łatwiej jest się zorientować, czy wszystko ok, czy nie? – TheVillageIdiot

14

The answer podanej przez @Kevinw jest całkowicie w porządku. Publikuję to jako tłumaczenie jego odpowiedzi na kod C#. Nie używam komentarzy, ponieważ nie będą one formatować kodu. Również używam try/catch, aby wiedzieć, czy transakcja powinna się zakończyć, czy zostać wycofana.

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

Wywołanie 'ts.Dispose()' wewnątrz klauzuli catch nie jest wymagane, ponieważ instrukcja using zajmie się tym i tak. W ogólnym przypadku może to nawet powodować problemy, ponieważ 'SharedDbConnectionScope' lub inny kod świadomy transakcji uruchomiony wewnątrz zakresu transakcji może zależeć od tego, czy zostanie usunięty zanim zostanie zamknięty zakres transakcji. –

+0

@OskarBerggren skomentował to. – TheVillageIdiot

1

Nie. Jeśli wstawię SharedDbConnectionScope poza zmianami, są one widoczne w bazie danych przed ts.Complete(). Włożenie go do środka blokuje serwer, dopóki operacja nie zostanie zakończona.

Powiązane problemy