Ich verwende C# und ADO.Net mit einem TransactionScope
, um eine Transaktion in einer ASP.Net App auszuführen. Diese Transaktion soll einige Daten über mehrere Tabellen hinweg speichern und dann eine E-Mail an die Abonnenten senden.Verwenden von TransactionScope um eine gespeicherte Prozedur mit Transaktion in SQL Server 2014
Frage: ist es eine gültige Verwendung von TransactionScope
, wenn es einen Anruf an eine gespeicherte Prozedur enthält, die eine eigene Transaktion in SQL Server 2014, oder soll ich die SQL-Transaktionsanweisungen dh begin tran
, commit tran
und rollback tran
Aussagen entfernen hat von der gespeicherten Prozedur aufgerufen wird innerhalb dieser TransactionScope
?
Der C# -Code für dieses Szenario und auch der T-SQL-Code der gespeicherten Prozedur werden beide unten erwähnt.
C# -Code mit TransactionScope
:
try
{
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection connection1 = new SqlConnection(connectString1))
{
// Opening the connection automatically enlists it in the
// TransactionScope as a lightweight transaction.
connection1.Open();
// SaveEmailData is a stored procedure that has a transaction within it
SqlCommand command1 = new SqlCommand("SaveEmailData", connection1);
command1.CommandType = CommandType.StoredProcedure;
command1.ExecuteNonQuery();
}
//Send Email using the helper method
EmailHelper.SendCustomerEmails(customerIds);
// The Complete method commits the transaction. If an exception has been thrown,
// Complete is not called and the transaction is rolled back.
scope.Complete();
}
}
catch(Exception ex)
{
Logger.Log(ex);
}
TSQL von Stored Procedure SaveEmailData
:
SET NOCOUNT ON
BEGIN TRY
DECLARE @emailToUserId BIGINT
BEGIN TRAN
-- //update statement. detail statement omitted
UPDATE TABLE1...
--update statement. detail statement omitted
UPDATE TABLE2...
IF @@trancount > 0
BEGIN
COMMIT TRAN
END
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN
END
EXEC Error_RaiseToADONET
END CATCH
Danke für die ausführliche Antwort. Meinten Sie, dass, wenn 'rollback tran' in der gespeicherten Prozedur aufgerufen wird, TransactionScope automatisch die gesamte Transaktion und nicht nur die Transaktion der gespeicherten Prozedur zurücksetzt, auch wenn kein Fehler von der Prozedur ausgelöst wird? – Sunil
Ja, wenn 'ROLLBACK TRAN' von TSQL aus aufgerufen wird, wird die Verbindung jede andere Arbeit rückgängig machen, die am Conn ausgeführt wird, z. von ADO. Nur wenn Sie 'SAVEPOINT' verwenden, können Sie den Umfang eines ROLLBACKs begrenzen. Beachten Sie jedoch, dass [SavePoints] (http://www.sommarskog.se/wishlist.html#savepointdistr) nicht mit Distributed Transactions arbeiten, was mit TransactionScope, z. wenn Sie gleichzeitig mehr als einen Conn im Bereich öffnen. Ich habe den einzigen Grund gefunden, 'BEGIN/COMMIT TRAN' in einem SPROC zu behalten, der von einer .Net App aufgerufen wird, wenn der SPROC auch anderswo ausgeführt werden muss, z. Ad-hoc von SSMS. – StuartLC
Aber rollback tran in gespeicherten Prozedur Rollback der TransactionScope-Transaktion nicht, es sei denn, ein Fehler wird auch von gespeicherten Prozedur ausgelöst, wenn Rollback-Anweisung aufgerufen wird? – Sunil