Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Annulation de la transaction interne d'une transaction imbriquée

SQL Server ne prend pas vraiment en charge les transactions imbriquées. Il n'y a qu'une seule transaction à la fois.

Cette transaction a un compteur de transaction imbriqué de base, @@TRANCOUNT . Chaque begin transaction consécutif incrémente le compteur de un, chaque commit transaction le réduit de un. Seul le commit qui réduit le compteur à 0 valide réellement la seule transaction.

Une rollback transaction annule la transaction et efface @@TRANCOUNT .

Dans votre cas, le résultat amusant est que SqlStatement3 est exécuté à l'extérieur une opération ! Votre commit final lèvera une exception "La demande COMMIT TRANSACTION n'a pas de BEGIN TRANSACTION correspondante", mais les effets de SqlStatement3 sont permanents.

Par exemple :

create table #t (col1 int)
insert #t (col1) values (1)
BEGIN TRANSACTION
update #t set col1 = 2 -- This gets rolled back
BEGIN TRANSACTION
update #t set col1 = 3 -- This gets rolled back too
ROLLBACK TRANSACTION
update #t set col1 = 4 -- This is run OUTSIDE a transaction!
COMMIT TRANSACTION -- Throws error
select col1 from #t

Imprime 4 . Vraiment. :)