221 messaggi dal 17 aprile 2006
Ciao a tutti,

descrivo la problematica:

ho una transazione di questo tipo

begin trans

--1 faccio una insert nella tabella A
--2 select dalla tabella A
--3 faccio varie operazione avvalendomi di tabelle temporanee #tmp che poi subito dopo droppo
--4 faccio alcuni update

IF @@ERROR <> 0 ROLLBACK TRAN
ELSE COMMIT TRAN
END

Premetto che il server è molto distante dai cliente per cui si potrebbero avere problemi di connessione durante la transazione.
Ecco cosa succede: alcune volte arrivo fino al punto 2 infatti al client arriva il risultato della select ma non sono eseguiti gli update punto 4.
ho letto in giro che l'uso delle tabelle temporanee nelle transazioni potrebbero causare problemi di rollback.

Voi che ne pensate?
Modificato da bluland il 11 gennaio 2013 19.17 -

Vincenzo Pesante
Software Engineer
1.024 messaggi dal 19 dicembre 2003
Contributi | Blog
Non so che cosa tu abbia "letto in giro", ma lascia stare quella strada.
Da come hai scritto l'istruzione sembra che tu faccia il controllo della @@ERROR solo al termine della quarta istruzione. Se è così il rollback della transazione può avvenire esclusivamente se ad andare in errore è l'istruzione appena precedente il @@ERROR.
Questa variabile globale viene aggiornata in occasione di ogni istruzione e anche la lettura stessa della @@ERROR resetta qualunque valore in essa memorizzato. Per questo motivo un errore che interviene nella prima, nella seconda o nella terza istruzione non sarà mantenuto al termine della quarta istruzione (dove tra l'altro scrivi "faccio alcuni update"; ognuno di essi aggiorna il valore della @@ERROR).
Per avere un comportamento coerente con quanto da te auspicato dovresti modificare il tutto in maniera simile a

BEGIN TRAN

1 faccio una insert nella tabella A
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RETURN
END

--2 select dalla tabella A
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RETURN
END

--3 faccio UNA SOLA operazione avvalendomi di tabelle temporanee #tmp che poi subito dopo droppo
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RETURN
END

--4 faccio UN SOLO update
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RETURN
END

COMMIT

Laddove volessi riutilizzare il codice di errore contenuto nella @@ERROR (magari per restituirlo come output della sp che esegue tutti questi comandi) dovresti memorizzarlo in una variabile PRIMA di leggerlo (altrimenti come detto subito dopo leggeresti un altro valore rispetto a quello che hai appena letto. Il controllo dovrebbe diventare quindi simile a

SET @myvar = @@ERROR
IF @myvar <> 0
BEGIN
ROLLBACK TRAN
Faccio quello che voglio con @myvar
RETURN
END

In alternativa a tutto questo puoi impostare l'opzione SET XACT_ABORT come descritto sul BOL

http://msdn.microsoft.com/library/ms188792.aspx

che rimuove la necessità di fare un controllo al termine di ogni istruzione per decidere se fare il rollback o continuare (con l'opzione a ON viene fatto automaticamente un rollback al verificarsi di un errore). Come ulteriore alternativa puoi utilizzare il TRY...CATCH di cui trovi info a partire da questo link

http://msdn.microsoft.com/library/ms175976.aspx

Bye

Luca Bianchi
Microsoft MVP - SQL Server
221 messaggi dal 17 aprile 2006
Ti ringrazio della risposta,
hai ragione è stata gestita malissimo, ho deciso di fare un controllo alla fine di ogni istruzione, anche se vorrei capire meglio XACT_ABORT che andrò subito a leggere.
Grazie della risposta

saluti

Vincenzo Pesante
Software Engineer

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.