Ho una procedura memorizzata che deve impostare un punto di salvataggio in modo che, in determinate circostanze, possa annullare tutto ciò che ha fatto e restituire un codice di errore al chiamante , o accettarlo/confermarlo e restituire il successo al chiamante. Ma ho bisogno che funzioni se il chiamante ha già avviato una transazione o meno. Il documento è estremamente confuso su questo argomento. Ecco quello che penso funzionerà, ma non sono certo di tutte le implicazioni.SAVE TRANSACTION vs BEGIN TRANSACTION (SQL Server) come nidificare correttamente le transazioni
Il fatto è che questo Stored Procedure (SP)
viene chiamato da altri. Quindi non so se hanno avviato una transazione o no ... Anche se richiedo agli utenti di avviare una transazione per utilizzare il mio SP, ho ancora domande sull'uso corretto di Save Points
...
My SP verificherà se una transazione è in corso e, in caso contrario, ne inizi una con BEGIN TRANSACTION
. Se una transazione è già in corso, creerà invece un punto di salvataggio con SAVE TRANSACTION MySavePointName
e salverà il fatto che questo è ciò che ho fatto.
Quindi, se devo ripristinare le modifiche, se ho fatto un BEGIN TRANSACTION
prima, quindi lo farò ROLLBACK TRANSACTION
. Se ho fatto il punto di salvataggio, allora lo farò ROLLBACK TRANSACTION MySavePointName
. Questo scenario sembra funzionare alla grande.
Ecco dove mi sento un po 'confuso - se voglio mantenere il lavoro che ho fatto, se avviò una transazione eseguirò COMMIT TRANSACTION
. Ma se ho creato un punto di salvataggio? Ho provato COMMIT TRANSACTION MySavePointName
, ma poi il chiamante cerca di impegnare il proprio transazione e ottiene un errore:
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
Quindi mi chiedo allora - un punto di salvataggio possibile eseguire il rollback (che funziona: ROLLBACK TRANSACTION MySavePointName
non rotolerà il chiamante del transazione). Ma forse non è mai necessario "commetterlo"? Rimane solo lì, nel caso in cui è necessario eseguire il rollback, ma si allontana una volta che la transazione originale è stata commessa (o ripristinata)?
Se c'è un modo "migliore" per "annidare" una transazione, per favore getta luce anche tu. Non ho capito come nidificare con BEGIN TRANSACTION
ma solo il rollback o il commit della mia transazione interna. Sembra che ROLLBACK
ricominci sempre alla transazione principale, mentre COMMIT
diminuisce semplicemente @@trancount
.
vostro ritrovamento potrebbe valere la pubblicazione come una risposta. –
@Andriy Ok, questo è quello che ho fatto: rimosso la mia modifica e usata come risposta. Grazie. –