Zombie transaction for dummies

by Luca Baldini on 5 aprile 2011

Durante lo sviluppo della versione 10.0 di Instant Developer mi è capitato di imbattermi in un problema grave e paradossale di Sql Server: le transazioni zombie! Questo articolo risulta un po’ tecnico ma sono convinto che il problema sia così grave che ritengo possa essere utile leggerlo, qualunque ambiente di sviluppo utilizziate per creare le vostre applicazioni.

Veniamo subito al problema: la transazione zombie. Sql Server possiede una funzionalità chiamata auto-rollback che viene automaticamente avviata dal server quando un client tenta di eseguire istruzioni che generano errori che il database ritiene gravi. Il problema è che il server avvia la procedura di rollback ma non avvisa il client che, quindi, prosegue senza sapere che, da quel momento in poi, sta lavorando fuori transazione in modalità auto-commit. Quando poi il client esegue l’istruzione di commit, il database risponde con un tardivo messaggio di errore: la transazione non è più disponibile.

Guardate questa immagine (la stessa sequenza di operazioni può essere riscritta in Java o C# in maniera molto simile):

Al termine della procedura ci si aspetterebbe che la tabella contenga sempre cinque righe in quanto la quarta istruzione di insert, racchiusa nel blocco try/catch, non può essere eseguita dato che contiene una data invalida. Purtroppo non è così: alla fine della procedura nella tabella sono presenti due righe perchè dopo le prime tre Sql Server ha eseguito l’auto-rollback lasciando in mano al client una transazione zombie; poi le successive istruzioni sono state eseguite in auto-commit senza che il client lo sapesse!

Se utilizzate le transazioni su Sql Server prestate molta attenzione alle operazioni che eseguite. Se una di queste fallisce è preferibile eseguire il rollback dell’intera transazione dato che non potete essere certi che il database non abbia anche lui avviato la stessa procedura.

{ 6 comments… read them below or add one }

1 Riccardo Bianco 5 aprile 2011 alle 11:47

Interessante

2 Teo 5 aprile 2011 alle 15:14

Analisi molto utile.
Grrazie Luca

3 Andrea Maioli 5 aprile 2011 alle 18:42

Anche Oracle fa scherzi con le transazioni. Se esegue uno statement DDL, esegue l’auto-commit della transazione precedente. Dalla documentazione: “A transaction begins with the first executable SQL statement. A transaction ends when it is committed or rolled back, either explicitly with a COMMIT or ROLLBACK statement or implicitly when a DDL statement is issued.”

4 Frieda 6 aprile 2011 alle 16:59

Una stored procedure e passa la paura.

5 Giuseppe Lanzi 7 aprile 2011 alle 14:01

@Frieda beh, a portela usare. Molte dinamiche applicative non si possono implementare con sole stored procedure.

6 Antonio Rughi 10 maggio 2011 alle 13:51

Grazie, molto utile a sapersi.
…e ripensandoci mi spiego anche alcuni problemi avuti in passato!

Leave a Comment

Previous post:

Next post: