2012-12-19 13 views
9

Ho 2 tabelle richiesta e dettagli. Il pulsante di salvataggio fare clic ho scrittoRollback in C#

fbsave(); 
fbsavedetails(); 

fbsave() salvare i dati nella tabella di indagine e fbsavedetails() salva i dati nella tabella di dettaglio.

ora se l'errore si verifica in fbsavedetails(), quindi entrambi i passaggi dovrebbero essere rollback.

è possibile?

+0

MS Access o SQL Server? – andy

+2

come si fa il livello dati? procedura di archiviazione? LINQ to SQL? collegato? scollegato? –

+0

Puoi fare ciò che vuoi usando le transazioni, http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction(v=vs.100).aspx – Raghuveer

risposta

8

È possibile creare in modo esplicito una transazione e passare che in giro, vale a dire

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

Si noti che qui si must anche impostare la Transaction su ogni comando, quindi il motivo per cui è necessario passare in, e tutto il i comandi devono essere sullo stesso oggetto di connessione.


Oppure: è possibile utilizzare TransactionScope; è importante che il Open() accade all'interno il TransactionScope per ottenere l'arruolamento automatica:

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

o:

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

con l'approccio TransactionScope, non c'è bisogno di impostare nulla di speciale - la maggior parte delle è automatico. Ovviamente è possibile passare facoltativamente la connessione nei metodi, ma potrebbero anche ottenere la propria connessione e, nella maggior parte dei casi, funzionerebbe correttamente.

+0

Il "open inside TransactionScope per ottenere l'inserimento automatico" annulla la necessità di DTC? –

+0

@MrMoose no, ma * si * di solito evita la necessità di DTC semplicemente passando la connessione: se si utilizza un solo oggetto di connessione all'interno di 'TransactionScope', esso viene gestito dall'LTM piuttosto che da DTC (in tutte le versioni di SQL Server> = 2005, IIRC) –

7

È possibile utilizzare TransactionScope.

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

se non si completa ilcorso di transazioni verrà eseguito il rollback.

1

ci sono due modi per risolvere questo problema

  1. uso DbTransaction e passare il DbTransaction intorno al due metodo, il commit della transazione se il successo e rollback se l'errore è accaduto contro: devono essere passati in giro DbTransaction.
  2. uso TransactionScope pro: la facilità di utilizzare contro: L'accesso non è supportato, e se il database è SQL2000, è richiesto msdtc essere configurato