[SQL 2008] Transazioni autonome

Published 08 ottobre 08 03.28 | abenedetti

SQL Server non ha, nativamente, il supporto alle transazioni autonome come ha, ad esempio, Oracle.

Prima di tutto, di cosa stiamo parlando?

Si definisce transazione autonoma una transazione che, innestata all'interno di un'altra, non ne subisce lo stato.

Cerco di spiegarmi con un esempio.

  • apro una transazione
    • provoco un errore esplicito (ad esempio una divisione per zero)
    • apro una seconda transazione
      • voglio loggare l'errore
    • chiudo la seconda transazione
  • chiudo la (prima) transazione

 

Fino a ieri (SQL 2005) la transazione interna era comunque influenzata dalla prima, quindi se fosse andata in rollback la prima sarebbe andata in rollback anche la seconda e... addio log della mia applicazione...

Oggi SQL Server 2008 introduce una nuova opzione server: remote proc transaction promotion (vedi msdn) che ci consente di isolare la tranazione, di renderla autonoma.

Vediamo un esempio pratico:

Use master go EXEC sp_addlinkedserver @server = N'myServer',@srvproduct = N' ',@provider = N'SQLNCLI', @datasrc = @@SERVERNAME EXEC sp_serveroption myServer,N'remote proc transaction promotion','FALSE' EXEC sp_serveroption myServer,N'RPC OUT','TRUE' go -- creo un database Ugiss IF EXISTS (SELECT name FROM sys.databases WHERE name = N'Ugiss') DROP DATABASE Ugiss GO CREATE DATABASE Ugiss GO Use Ugiss go -- creo la tabella di log create table applicationLog ( idRecord int primary key identity(1,1), data datetime default(getdate()), descrizione varchar(200) ) go -- stored procedure per insert log create procedure up_insertApplicationLog ( @descrizione varchar(200) ) AS set nocount on insert applicationLog (descrizione) values (@descrizione) set nocount off go /* start test transazione autonoma */ declare @errorCode int begin tran appTran select 1/0 select @errorCode = @@error if (@errorCode <> 0) begin begin tran autTran declare @str varchar(200) set @str = 'Attenzione: errore ' + cast(@errorCode as varchar(10)) -- chiamo la procedura tramite linked server exec myServer.Ugiss.dbo.up_insertApplicationLog @str commit tran autTran rollback tran appTran end if (@@TRANCOUNT > 0) commit tran appTran go -- vedo la tabella di log select * from applicationLog go exec sp_dropserver 'myServer' go

Il risultato che otterremo, nei messaggi, sarà proprio l'errore:

Msg 8134, Level 16, State 1, Line 6
Divide by zero error encountered.

Ma questa volta la nostra tabella di log sarà popolata!

image

Comments

# Sql non transazionale all'interno di transazione | hilpers said on marzo 17, 2009 02.06 :

Pingback from  Sql non transazionale all'interno di transazione | hilpers

This Blog

Syndication