Używam C# i ADO.Net z TransactionScope
do uruchomienia transakcji w aplikacji ASP.Net. Ta transakcja ma na celu zapisanie niektórych danych w wielu tabelach, a następnie wysłanie e-maila do subskrybentów.Korzystanie z TransactionScope wokół procedura składowana z transakcji w SQL Server 2014
Pytanie: czy jest to ważne zastosowanie TransactionScope
, gdy zawiera wywołanie procedury przechowywanej, który ma swój własny transakcji w SQL Server 2014, czy powinienem usunąć oświadczenia transakcji SQL tj begin tran
, commit tran
i rollback tran
sprawozdań z procedura składowana jest wywoływana w ramach tej TransactionScope
?
Kod C# dla tego scenariusza oraz kod T-SQL procedury składowanej są wymienione poniżej.
kod C# za pomocą 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 procedury przechowywanej 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
Dzięki za szczegółową odpowiedź. Czy miałeś na myśli to, że jeśli w procedurze przechowywanej zostanie wywołany "rollback tran", to TransactionScope automatycznie wycofa całą transakcję, a nie tylko transakcję w procedurze przechowywanej, nawet jeśli nie zostanie zgłoszony błąd z procedury? – Sunil
Tak, wywołanie 'ROLLBACK TRAN' z TSQL na tym samym połączeniu spowoduje cofnięcie wszelkich innych prac wykonanych na urządzeniu Conn, np. przez ADO. Tylko jeśli użyjesz 'SAVEPOINT', możesz ograniczyć zakres ROLLBACK. Należy jednak pamiętać, że [SavePoints] (http://www.sommarskog.se/wishlist.html#savepointdistr) nie działają z transakcjami rozproszonymi, co może się zdarzyć dość subtelnie w przypadku transakcji TransactionScope, np. jeśli otworzysz więcej niż jedno połączenie w tym samym czasie. Znalazłem jedyny powód, dla którego 'BEGIN/COMMIT TRAN' w SPROC nazwie przez .Net App jest, jeśli SPROC również musi być wykonany w innym miejscu np. ad-hoc z SSMS. – StuartLC
Ale wycofanie tran w procedurze przechowywanej nie spowoduje wycofania transakcji TransactionScope, chyba że zostanie również zgłoszony błąd z procedury składowanej, gdy zostanie wywołana instrukcja wycofania transakcji? – Sunil