siquellando

...scoperte e considerazioni Sql di uno sviluppista
(un po' sviluppatore e un po' sistemista)

aprile 2008 - Posts

Nested Transition ... attenzione, non ci sono

In questi giorni parlando con vari utenti ho realizzato che, a volte, c'e' un po' di confusione in merito alla possibilita' di avere transazioni annidate in Sql Server.

Forse vale la pena di fare un po' di chiarezza: SqlServer NON supporta "Transazioni Annidate".

In altre parole per ciascuna connessione puo' esistere solo una transazione attiva.

E il fatto che sia possibile (almeno sintatticamente) sottomettere piu' statement BEGIN TRANSACTION complica e confonde le cose Huh?

In realta' ogni volta che viene sottomesso un BEGIN TRAN SqlServer semplicemente incrementa un contatore interno il cui valore e' recuperabile con una select sulla funzione @@trancount.

Ad ogni commit il valore di @@trancount diminuisce di un unita' e solo l'ultimo commit (che riporta @@trancount a zero) committa realmente la transazione.

In compenso qualunque rollback provoca l'annullamento di tutte le operazioni a partire dal primo begin tran (ovvero viene annullata la transazione piu' esterna).

Pertanto sottomettendo il seguente codice:

begin tran;

insert into Test values (1);

begin tran;

insert into Test values (2);

- rolback di tutto (anche l'insert col valore 1)

rollback;

-- questo commit da errore: la transazione e' chiusa

commit;

Nella tabella Test non verra' inserito alcun valore, in quanto il primo rollback cancella tutte le attivita' iniziate con la transazione piu' esterna.

 

Inoltre, per committare davvero, bisogna prestare attenzione a sottomettere un numero di COMMIT uguale al numero di BEGIN TRAN  (@@trancount) altrimenti si rischia di lasciare aperta la transazione con tutti i pericoli di lock che seguono. 

 

Attenzione che ci sono situazioni (ad esempio se l'utente ha dato un cancel) in cui, anche se viene generato un errore, non viene chiusa la transazione Surprise  Pertanto e' buona norma verificare se ci sono transazioni attive prima di risottomettere nuovamente un BEGIN TRAN e trovarsi con qualche "parentesi non chiusa" Smile