sql >> Databáze >  >> RDS >> Sqlserver

Vnořené uložené procedury obsahující vzor TRY CATCH ROLLBACK?

Toto je naše šablona (protokolování chyb odstraněno)

Toto je navrženo tak, aby zvládlo

Vysvětlení:

  • všechny TXN begin a commit/rollbacks musí být spárovány tak, aby @@TRANCOUNT je stejný na vstupu i výstupu

  • neshody @@TRANCOUNT způsobit chybu 266, protože

    • BEGIN TRAN přírůstky @@TRANCOUNT

    • COMMIT sníží @@TRANCOUNT

    • ROLLBACK vrátí @@TRANCOUNT na nulu

  • Nemůžete snížit @@TRANCOUNT pro aktuální rozsah
    To je to, co si myslíte, že je "vnitřní transakce"

  • SET XACT_ABORT ON potlačí chybu 266 způsobenou neshodou @@TRANCOUNT
    A také se zabývá podobnými problémy "Časový limit transakce SQL Serveru" na dba.se

  • To umožňuje TXN na straně klienta (jako LINQ) Jedna uložená procedura může být součástí distribuované transakce nebo transakce XA, nebo jednoduše iniciovaná v kódu klienta (řekněme .net TransactionScope)

Použití:

  • Každý uložený proces musí odpovídat stejné šabloně

Shrnutí

  • Nevytvářejte tedy více TXN, než potřebujete

Kód

CREATE PROCEDURE [Name]
AS
SET XACT_ABORT, NOCOUNT ON

DECLARE @starttrancount int

BEGIN TRY
    SELECT @starttrancount = @@TRANCOUNT

    IF @starttrancount = 0
        BEGIN TRANSACTION

       [...Perform work, call nested procedures...]

    IF @starttrancount = 0 
        COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 AND @starttrancount = 0 
        ROLLBACK TRANSACTION;
    THROW;
    --before SQL Server 2012 use 
    --RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
END CATCH
GO

Poznámky:

  • Kontrola vrácení zpět je ve skutečnosti nadbytečná, protože SET XACT_ABORT ON . Cítím se však díky němu lépe, vypadá bez něj divně a umožňuje situace, kdy ho nechcete mít zapnutý

  • Remus Rusanupodobný shell který používá body uložení. Preferuji volání atomické DB a nepoužívám dílčí aktualizace jako jejich článek



  1. Chcete získat seznam všech mladších lékařů pracujících pod starším lékařem a naopak?

  2. zřetězení spojení zpět do cílové tabulky

  3. Potřebujete pomoc s unpivot v mysql s více sloupci data

  4. TEXT vs VARCHAR v InnoDB MySQL 5.5. Kdy použít každý z nich