Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Procedure archiviate nidificate contenenti pattern TRY CATCH ROLLBACK?

Questo è il nostro modello (registrazione errori rimossa)

Questo è progettato per gestire

Spiegazioni:

  • tutti i TXN iniziano e i commit/rollback devono essere accoppiati in modo che @@TRANCOUNT è lo stesso in entrata e in uscita

  • mancate corrispondenze di @@TRANCOUNT causare l'errore 266 perché

    • BEGIN TRAN incrementi @@TRANCOUNT

    • COMMIT decrementa @@TRANCOUNT

    • ROLLBACK restituisce @@TRANCOUNT a zero

  • Non puoi decrementare @@TRANCOUNT per l'ambito attuale
    Questa è quella che penseresti sia la "transazione interna"

  • SET XACT_ABORT ON elimina l'errore 266 causato da @@TRANCOUNT non corrispondenti
    E si occupa anche di problemi come questo "SQL Server Transaction Timeout" su dba.se

  • Ciò consente TXN lato client (come LINQ) Una singola stored procedure può far parte di una transazione distribuita o XA o semplicemente una avviata nel codice client (ad esempio .net TransactionScope)

Utilizzo:

  • Ogni processo memorizzato deve essere conforme allo stesso modello

Riepilogo

  • Quindi non creare più TXN del necessario

Il codice

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

Note:

  • Il controllo del rollback è effettivamente ridondante a causa di SET XACT_ABORT ON . Tuttavia, mi fa sentire meglio, sembra strano senza e consente situazioni in cui non lo vuoi su

  • Remus Rusanu ha una shell simile che utilizza punti di salvataggio. Preferisco una chiamata DB atomica e non utilizzo aggiornamenti parziali come il loro articolo