Transazioni in Sql Server 2005

sabato 26 luglio 2008 - 11.25

tarabasch84 Profilo | Junior Member

Salve ragazzi,
ho realizzato una SP che effettua una serie di operazioni CRUD su diverse tabelle. Chiaramente ho dovuto utilizzare una transazione esplicita al fine di evitare che in caso di errore, venga modificato il database. Vorrei sapere come faccio ad intercettare un eventuale errore nel blocco al fine di annullare la transazione con un rollback.
In che modo dovrei strutturare la mia SP?
Saluti Aldo




Credo che parte della colpa sia di billy...

lbenaglia Profilo | Guru

>Vorrei sapere come faccio ad intercettare un eventuale
>errore nel blocco al fine di annullare la transazione con un
>rollback.
>In che modo dovrei strutturare la mia SP?

Ciao Aldo,

incapsula le tue operazioni CRUD in un blocco TRY...CATCH.
Leggi questo paragrafo sui BOL:

"Using TRY...CATCH in Transact-SQL"
http://technet.microsoft.com/en-us/library/ms179296.aspx

>Saluti Aldo
Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

tarabasch84 Profilo | Junior Member

Ho dato uno sguardo al link che mi hai passato. Tutto chiaro per quanto concerne l'uso del try/catch. Quindi per intercettare qualsiasi errore di una certa gravità, dovrei inserire all'interno del costrutto try/catch la transazione e chiamare il rollback in caso di errore. Però non mi è chiaro l'utilizzo di XACT_STATE(). Dovrei utilizzarlo sempre e comunque all'interno del blocco catch per rollbakkare la transaction?
Credo che parte della colpa sia di billy...

lbenaglia Profilo | Guru

>Ho dato uno sguardo al link che mi hai passato. Tutto chiaro
>per quanto concerne l'uso del try/catch. Quindi per intercettare
>qualsiasi errore di una certa gravità, dovrei inserire all'interno
>del costrutto try/catch la transazione e chiamare il rollback
>in caso di errore.
Occhio che "A TRY…CATCH construct catches all execution errors that have a severity higher than 10 that do not close the database connection." quindi esistono tutta una serie di eccezioni che dovrai necessariamente gestire lato client (ad es. quelle gravi che determinano la chiusura della connessione).

>Però non mi è chiaro l'utilizzo di XACT_STATE().
>Dovrei utilizzarlo sempre e comunque all'interno del blocco catch
>per rollbakkare la transaction?
Sempre no, ma ti aiuterebbe ad identificare le "doomed transactions", ovvero quelle transazioni abortite a causa di un errore grave (con elevata severity) che causano l'interruzione dell'intero batch. Queste transazioni "appese" non permettono alcuna commit e devono necessariamente essere annullate.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

tarabasch84 Profilo | Junior Member

>quindi esistono tutta una serie di eccezioni che
>dovrai necessariamente gestire lato client (ad es. quelle gravi
>che determinano la chiusura della connessione).
in che modo?

>Sempre no, ma ti aiuterebbe ad identificare le "doomed transactions",
>ovvero quelle transazioni abortite a causa di un errore grave
>(con elevata severity) che causano l'interruzione dell'intero
>batch. Queste transazioni "appese" non permettono alcuna commit
>e devono necessariamente essere annullate.
Come faccio per annullare la transazione in tal caso?


Credo che parte della colpa sia di billy...

lbenaglia Profilo | Guru

>>quindi esistono tutta una serie di eccezioni che
>>dovrai necessariamente gestire lato client (ad es. quelle gravi
>>che determinano la chiusura della connessione).
>in che modo?
Dipende dal linguaggio di programmazione che usi e dalla modalità di accesso ai dati.
In questo articolo Erland ti spiega un bel po' di cosine:
http://www.sommarskog.se/error-handling-I.html

>>Sempre no, ma ti aiuterebbe ad identificare le "doomed transactions",
>>ovvero quelle transazioni abortite a causa di un errore grave
>>(con elevata severity) che causano l'interruzione dell'intero
>>batch. Queste transazioni "appese" non permettono alcuna commit
>>e devono necessariamente essere annullate.
>Come faccio per annullare la transazione in tal caso?
ROLLBACK TRAN

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

tarabasch84 Profilo | Junior Member

Il link che mi hai passato è molto interessante, appena avrò tempo mi darò una bella lettura. Grazie!
Riassumendo, la transazione va inglobata all'interno di un costrutto try/catch. In caso di errore di qualsiasi severità l'esecuzione della transazione passa nelle mani del catch all'interno del quale la transazione viene annullata con un rollback:
begin try
begin transaction
...
...
commit transaction
end try
begin catch
rollback transaction
end catch
La gestione degli errori la implemento all'interno del blocco catch magari con una SP che mi memorizza all'interno di un tabella apposita informazioni quali error_number(), error_state(), etc.
Che ne pensi?

>Sempre no, ma ti aiuterebbe ad identificare le "doomed transactions",
>ovvero quelle transazioni abortite a causa di un errore grave
>(con elevata severity) che causano l'interruzione dell'intero
>batch. Queste transazioni "appese" non permettono alcuna commit
>e devono necessariamente essere annullate.
Perchè potrebbe ritornarmi utile identificare transazioni abortite a causa di un errore grave piuttosto che transazioni annullate per un errore non grave?

--
Credo che parte della colpa sia di billy...

lbenaglia Profilo | Guru

>In caso di errore di qualsiasi severità l'esecuzione
>della transazione passa nelle mani del catch
No, se la severity è grave può cadere la connessione in qualsiasi punto del tuo codice o addirittura arrestare il DB Engine.

>Perchè potrebbe ritornarmi utile identificare transazioni abortite
>a causa di un errore grave piuttosto che transazioni annullate
>per un errore non grave?
Che significa questa domanda?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

tarabasch84 Profilo | Junior Member

Prima mi dicevi che XACT_STATE() non è sempre necessario utilizzarlo. Ma come faccio a sapere quando lo è e quando non lo è?
--
Credo che parte della colpa sia di billy...

lbenaglia Profilo | Guru

>Prima mi dicevi che XACT_STATE() non è sempre necessario utilizzarlo.
>Ma come faccio a sapere quando lo è e quando non lo è?
Diciamo che non esiste una regola scritta e anche i BOL sono piuttosto vaghi sull'argomento.
Vuoi sapere come farei io?

BEGIN TRY BEGIN TRANSACTION; ... COMMIT TRANSACTION; END TRY BEGIN CATCH IF (XACT_STATE()) = -1 BEGIN ROLLBACK TRANSACTION; END; IF (XACT_STATE()) = 1 BEGIN COMMIT TRANSACTION; END; END CATCH; GO

Qualcosa del genere
Eventualmente nel blocco CATCH puoi loggare come meglio credi il messaggio d'errore.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

tarabasch84 Profilo | Junior Member

Ok! Penso di aver compreso.
Ti ringrazio. Ciao!
--
Credo che parte della colpa sia di billy...
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5