2012-12-19 25 views
9

Mam 2 zapytania tabelaryczne i szczegóły. SAVE kliknij przycisk pisałemCofnij w C#

fbsave(); 
fbsavedetails(); 

fbsave() zapisać dane w tabeli zapytania i fbsavedetails() zapisuje dane w tabeli Danych.

teraz, jeśli wystąpi błąd w fbsavedetails(), oba kroki powinny zostać wycofane.

czy to możliwe?

+0

MS Access lub SQL Server? – andy

+2

Jak zrobić swoją warstwę danych? przechowywane procedury? linq-sql? połączony? niepowiązany? –

+0

Możesz robić, co chcesz, korzystając z transakcji, http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction(v=vs.100).aspx – Raghuveer

Odpowiedz

8

Można jawnie utworzyć transakcję i przekazać, że ok, tzn

using(var connection = ...) 
{ 
    connection.Open(); 
    using (var tran = connection.BeginTransaction()) 
    { 
     try 
     { 
      FBSave(connection, tran); 
      FBSaveDetails(connection, tran); 
      tran.Commit(); 
     } 
     catch 
     { 
      tran.Rollback(); 
      throw; 
     } 
    } 
} 

Zauważ, że tutaj jesteś koniecznością również ustawić Transaction na każdej komendy, więc dlaczego trzeba przekazać go, a wszystkie komendy muszą znajdować się na tym samym obiekcie połączenia.


Lub: można użyć TransactionScope; ważne jest, że Open() dzieje wewnątrzTransactionScope aby uzyskać automatyczne wstępowania:

using(var tran = new TransactionScope()) 
{ 
    FBSave(); 
    FBSaveDetails(); 
    tran.Complete(); 
} 

czyli

using(var tran = new TransactionScope()) 
using(var connection = ...) 
{ 
    connection.Open(); 
    FBSave(connection); 
    FBSaveDetails(connection); 
    tran.Complete(); 
} 

z podejściem TransactionScope, nie trzeba ustawić coś specjalnego - większość to jest automatyczne. Można oczywiście opcjonalnie przekazać połączenie metodom, ale mogą one również uzyskać własne połączenie, w większości przypadków będzie działało dobrze.

+0

Czy "otwarty wewnątrz TransactionScope, aby uzyskać automatyczne rejestrowanie" neguje potrzebę kodu DTC? –

+0

@MrMoose no, ale * możesz * zwykle uniknąć potrzeby wystąpienia kodu DTC, po prostu przekazując połączenie: jeśli użyjesz tylko jednego obiektu połączenia wewnątrz 'TransactionScope', to zostanie on obsłużony przez LTM zamiast DTC (we wszystkich wersjach SQL Server> = 2005, IIRC) –

7

Możesz użyć TransactionScope.

using(var scope = new TransactionScope()) 
{ 
    //Complete the transaction only when both inserts succeed. 
    scope.Complete(); 
} 

jeśli nie zakończysz transakcji, zostanie ona wycofana.

1

istnieją dwa sposoby, aby rozwiązać ten problem

  1. użytkowania DbTransaction i przekazać DbTransaction wokół dwóch sposobie zatwierdzania transakcji, jeśli sukces i wycofywania jeśli błąd się Wady: DbTransaction muszą być przekazywane dookoła.
  2. użycie TransactionScope Plusy: łatwość w użyciu Wady: Access nie jest obsługiwany, a jeśli baza danych jest SQL2000, msdtc wymagane jest skonfigurowany