Jestem programistą C# uczącym się więcej TSQL. Napisałem skrypt tak:Czy transakcja wymaga próby złapania?
begin transaction
--Insert into several tables
end transaction
Ale powiedziano mi, że nie był to dobry pomysł i użyć czegoś takiego:
BEGIN TRANSACTION;
BEGIN TRY
-- Generate a constraint violation error.
DELETE FROM Production.Product
WHERE ProductID = 980;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
nie widzę dlaczego Drugim przykładem jest bardziej poprawne . Czy pierwszy nie działałby w ten sam sposób? Wydaje się, że pierwsza z nich zaktualizowałaby wszystkie tabele, lub w ogóle nie? Nie rozumiem, dlaczego sprawdzenie @@TRANCOUNT
jest konieczne przed zatwierdzeniem.
Zrobiłbym taki sam argument, jak ty. Dodatkowo zalecany wzorzec try/catch to anty-wzór, który nazywam try/squelch. Przechwytuje i popełnia błąd, a następnie kontynuuje po cichu. To NIE obsługuje błędów, to je tłumi. W związku z tym blok transakcji typu try/catch nie jest wymagany w przypadku transakcji. Zwłaszcza jeśli jesteś w wyzwalaczu, użycie try/catch prawdopodobnie spowoduje znacznie więcej problemów niż kiedykolwiek rozwiąże. –
Jeśli cokolwiek w drugim przykładzie, zatwierdzenie powinno znajdować się w bloku try, a nie po catch ... myślę, że – Kritner