2014-09-13 5 views

risposta

6

Se il processo è solo chiamando un singolo stored procedure in un unico SqlCommand, poi basta gestire la transazione all'interno della stored procedure e non v'è alcuna necessità di gestirlo dal codice C#. Dovresti solo gestirlo nel codice C# per mantenere la transazione su più esecuzioni SqlCommand.

FYI, gestire l'operazione in entrambi i livelli è necessario solo se entrambe le seguenti sono vere:

  • il codice C# sta facendo più SqlCommand chiamate che devono essere considerati una singola operazione
  • la stored le procedure possono/devono essere richiamate al di fuori di questo codice C#, ad esempio da altre stored procedure (nel qual caso potrebbe non esserci una Transazione esistente nel momento in cui le stored procedure sono/sono chiamate.

Esterno o Se lo scenario sopra descritto, la gestione della transazione in entrambi gli strati è inutile in quanto esiste una sola transazione. Se la transazione viene avviata nel codice C#, tutto ciò che accade nella stored procedure quando viene chiamato BEGIN TRAN è che viene incrementato @@TRANCOUNT. E la transazione non viene realmente impegnata fino a quando lo @@TRANCOUNT torna indietro a 0 emettendo lo stesso numero di s come mostrato in @@TRANCOUNT (in questo caso, emettendo uno COMMIT nella stored procedure e nuovamente nel codice C#, in quale punto SQL Il server effettivamente fa il vero "commit"). Tuttavia, un singolo ROLLBACK riporta @@TRANCOUNT su 0 indipendentemente dal numero a cui era. E se ciò accade nella Proc. Memorizzata, non è possibile emettere uno COMMIT o ROLLBACK nel codice C# poiché la transazione non esiste più, quindi è necessario prima verificare una transazione attiva.

Supponendo che si stia utilizzando almeno SQL Server 2005, se non più recente, assicurarsi di utilizzare la sintassi T-SQL TRY/CATCH per gestire lo COMMIT/ROLLBACK all'interno della stored procedure. Avrete bisogno della sintassi TRY/CATCH per catturare correttamente gli errori ed uscire dal proc (s) anche se si sta gestendo solo la transazione nel codice C#.

Ad esempio:

BEGIN TRY 

    BEGIN TRAN; 

    UPDATE Table1 ... ; 

    UPDATE Table2 ... ; 

    UPDATE Table3 ... ; 

    COMMIT TRAN; 

END TRY 
BEGIN CATCH 

    IF (@@TRANCOUNT > 0) 
    BEGIN 
    ROLLBACK TRAN; 
    END; 

    THROW; -- if using SQL Server 2012 or newer, else use RAISERROR 

END CATCH; 
+0

Oh dio, le transazioni di SQL Server nidificate .. evitare come la peste. Almeno i trigger non sono coinvolti. Questa è una delle poche aree in cui avrei dato un calcio a uno sviluppatore di SQL Server, se ne avesse la possibilità. – user2864740

+0

Grazie mille ... Sto eseguendo più SqlCommand e ogni comando sta aggiornando più tabelle utilizzando proc in Sql Server 2008 R2, quindi in tal caso se utilizzo Transaction solo a livello di codice C#, funzionerebbe correttamente? –

+0

@AbhishekSrivastava: controlla la mia risposta aggiornata come ho affrontato tale scenario mentre devi aver aggiunto il commento ;-). Tutto dipende dal fatto che le Stored Procedures possano essere richiamate da altre Stored Procedures o individualmente da un altro codice C# che potrebbe non essere incluso in una transazione. –