SAVE TRANSACTION vs BEGIN TRANSACTION (SQL Server) comment bien imbriquer des transactions
J'ai une procédure stockée qui doit mettre un point de sauvegarde, de sorte qu'il peut, dans certaines circonstances, de défaire tout ce qu'il a fait et retourner un code d'erreur à l'appelant, ou d'accepter/de s'engager et de retour de réussite à l'appelant. Mais j'en ai besoin pour travailler de savoir si l'appelant a déjà commencé une transaction ou pas. La doc est très confus sur ce sujet. Voici ce que je pense de fonctionner, mais je ne suis pas certain de toutes les ramifications.
La chose est - ce Stored Procedure (SP)
est appelé par d'autres. Donc je ne sais pas si ils ont lancé une opération ou pas... Même si j'ai besoin d'utilisateurs pour démarrer une transaction à utiliser mon SP, j'ai encore des questions sur l'utilisation appropriée de Save Points
...
Mon SP permettra de tester si une transaction est en cours, et si pas, créez-en une avec BEGIN TRANSACTION
. Si une transaction est déjà en cours, qu'il va plutôt créer un point de sauvegarde avec SAVE TRANSACTION MySavePointName
et d'enregistrer le fait, c'est ce que j'ai fait.
Alors si j'ai à faire reculer mes modifications, si je fait un BEGIN TRANSACTION
plus tôt, alors je vais ROLLBACK TRANSACTION
. Si j'ai fait le point de sauvegarde, puis je vais ROLLBACK TRANSACTION MySavePointName
. Ce scénario semble fonctionner à merveille.
C'est là que je suis un peu confus - si je veux continuer le travail que j'ai fait, si j'ai commencé une opération, je vais exécuter COMMIT TRANSACTION
. Mais si j'ai créé un point de sauvegarde? J'ai essayé COMMIT TRANSACTION MySavePointName
mais alors le visiteur tente de valider sa transaction et obtient une erreur:
La TRANSACTION de validation demande n'a pas de correspondant COMMENCER la TRANSACTION.
Alors je me demandais alors - un point de sauvegarde peut être restaurée (qui fonctionne: ROLLBACK TRANSACTION MySavePointName
ne sera PAS revenir en arrière à l'appelant de la transaction). Mais peut-être que l'on n'a jamais besoin de "s'engager"? Il reste simplement là, dans le cas où vous avez besoin de revenir à elle, mais disparaît une fois l'original de la transaction est validée (ou annulée)?
Si il ya une "meilleure façon" d'un "nid" d'une opération, veuillez jeter un peu de lumière. Je n'ai pas compris comment faire son nid avec BEGIN TRANSACTION
mais seulement de restauration ou de commettre l'intérieur de ma transaction. Semble ROLLBACK
va toujours revenir en haut de la transaction, tandis que COMMIT
simplement décrémente @@trancount
.
source d'informationauteur Brian B
Vous devez vous connecter pour publier un commentaire.
Je crois que j'ai compris tout cela maintenant, alors je vais répondre à ma propre question...
J'ai même tenu un blog mes conclusions, si vous voulez plus de détails à http://geekswithblogs.net/bbiales/archive/2012/03/15/how-to-nest-transactions-nicely---quotbegin-transactionquot-vs-quotsave.aspx
Donc mon SP commence avec quelque chose comme ça, pour démarrer une nouvelle transaction si il n'y a aucun, mais utiliser un Point de sauvegarde si l'on est déjà en cours:
Ensuite, lorsque vous êtes prêt à valider les modifications, vous avez seulement besoin d'engager si nous avons commencé l'opération de nous-mêmes:
Et enfin, pour revenir simplement vos modifications jusqu'à présent:
L'extension de Brian B de la réponse de.
Cela garantit le point de sauvegarde nom est unique et utilise le nouveau TRY/CATCH/JETER des fonctionnalités de SQL Server 2012.
J'ai utilisé ce type de transaction manager dans mes Procédures Stockées :