Questo è il nostro modello (registrazione errori rimossa)
Questo è progettato per gestire
- Articolo di Paul Randal "Nessuna transazione nidificata in SQL Server"
- Errore 266
- Trigger rollback
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