Dette er vores skabelon (fejllogning fjernet)
Dette er designet til at håndtere
- Paul Randals artikel "Intet sådan noget som en indlejret transaktion i SQL Server"
- Fejl 266
- Trigger rollbacks
Forklaringer:
-
alle TXN-begynder og commit/rollbacks skal parres, så
@@TRANCOUNT
er det samme ved ind- og udrejse -
uoverensstemmelser af
@@TRANCOUNT
forårsage fejl 266 fordi-
BEGIN TRAN
trin@@TRANCOUNT
-
COMMIT
nedsætter@@TRANCOUNT
-
ROLLBACK
returnerer@@TRANCOUNT
til nul
-
-
Du kan ikke formindske
@@TRANCOUNT
for det nuværende omfang
Dette er, hvad du tror er den "indre transaktion" -
SET XACT_ABORT ON
undertrykker fejl 266 forårsaget af uoverensstemmende@@TRANCOUNT
Og behandler også problemer som dette "SQL Server Transaction Timeout" på dba.se -
Dette giver mulighed for TXN'er på klientsiden (som LINQ) En enkelt lagret procedure kan være en del af en distribueret eller XA transaktion, eller blot en initieret i klientkoden (f.eks. .net TransactionScope)
Brug:
- Hver lagrede proc skal være i overensstemmelse med den samme skabelon
Oversigt
- Så opret ikke flere TXN'er, end du har brug for
Koden
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
Bemærkninger:
-
Tilbageføringskontrollen er faktisk overflødig på grund af
SET XACT_ABORT ON
. Det får mig dog til at føle mig bedre, ser mærkeligt ud uden og giver mulighed for situationer, hvor du ikke vil have det tændt -
Remus Rusanu har en lignende skal der bruger sparepoint. Jeg foretrækker et atomic DB-kald og bruger ikke delvise opdateringer som deres artikel