J'ai récemment exécuté une requête de mise à jour sur 100 000 enregistrements. J'ai réalisé que j'avais fait une erreur pendant l'exécution de la requête et j'ai rapidement débranché le câble réseau.
La requête de mise à jour
- arrêter le traitement et complètement annuler?
- poursuivre le traitement jusqu'à la fin et valider?
- arrêter le traitement et ne mettre à jour qu'une partie des lignes cibles?
sql-server
network
robocop
la source
la source
Réponses:
Comme mentionné par Nick et Martin, le statut final de votre requête dépend de si SQL Server est au courant de votre tirage de câble réseau avant la fin de la requête. De Books Online (bien que je trouve intéressant qu'il y ait des sujets équivalents pour cela en 2000 , 2005 , 2008 et 2008 R2 , mais pas 2012 ou 2014):
(En passant, ce mot connexions dans l'avant-dernière phrase était probablement censé être des transactions . Je ne sais pas comment on annule une connexion.)
De la même manière, SQL Server peut annuler ou rétablir les transactions pendant la récupération après l'arrêt inattendu du serveur, et cela dépendra de l'état de la transaction au moment de l'arrêt. J'ai vu des gens utiliser cette tactique pour réaliser ce que vous tentiez de faire (annuler la (les) transaction (s)) et lorsque le serveur a redémarré une grande partie du travail a simplement été refaite (donc l'effet net de leur réaction de genou était beaucoup plus proche). à zéro que prévu).
Donc, plutôt que d'être soumis à cela, au lieu de faire des choses drastiques dans la panique, comme tirer un câble réseau ou éteindre la machine, je suggère à l'avenir que vous ayez une meilleure discipline pour exécuter des requêtes ad hoc sur des systèmes importants. Par exemple, au lieu de:
Avoir ceci:
Ensuite, si la mise à jour était en effet correcte, vous pouvez mettre en surbrillance la
COMMIT
pièce et l'exécuter. Si ce n'est pas le cas, vous pouvez calmement mettre en évidence laROLLBACK
pièce et l'exécuter. Vous pouvez même utiliser des compléments tels que SSMS Tools Pack pour modifier votreNew Query
modèle afin d'inclure ce passe-partout.Maintenant, il pourrait toujours vous poser des problèmes dans le cas où vous exécutez la requête et que vous ne validiez ni ne rétrogradiez, car maintenant votre transaction bloque d'autres utilisateurs. Mais cela vaut mieux que de modifier irrévocablement les données.
Et bien sûr, comme toujours, disposez d'une sauvegarde sur laquelle vous pouvez compter.
la source
@Aaron a raison. Créer une transaction avant vos commandes est votre meilleur pari. Si vous ne vous souvenez pas de le faire, une option consiste à entrer dans le
Tools-Options
paramètre et à activerSET IMPLICIT_TRANSACTIONS
. Cela démarrera automatiquement une transaction dès que certaines commandes seront exécutées. Cela inclutUPDATE
,DELETE
etc. Cela semble être une liste assez complète de toute commande qui ferait"change"
quelque chose.SELECT
est également inclus dans la liste etwill
démarre une transaction. Vous pouvez voir une liste complète des commandes qui démarrent une transaction avec ce paramètre ici . Il ne créera pas de transaction si une est déjà démarrée. Maintenant, l'inconvénient est que vous devrez vous souvenir deCOMMIT
tout changement effectué.REMARQUE: Sur la base de la suggestion de @ Aaron, je vais souligner à nouveau cela.
Fondamentalement, vous échangez en oubliant
BEGIN
une transaction et en gâchant quelque chose, pour oublierCOMMIT
une transaction et la suspendre si vous la laissez ouverte puis partez pour la journée. J'ai testé juste la fermeture d'une fenêtre de requête en pensant qu'elle annulerait ma transaction, mais cela m'a demandé si je voulais valider ou annuler la transaction.la source
SELECT
va démarrer une transaction (qui est également documentée dans le lien que vous avez publié)je pense que cela dépend vraiment:
si la commande atteint déjà le serveur avant de débrancher le câble réseau, la commande continuera à s'exécuter normalement.
si vous avez un TransactionScope (utilisé dans .Net, pas sûr d'autres langues) pour encapsuler toutes les commandes de mise à jour, vous ne pouvez probablement arrêter la transaction à être validée que si le transactionScope.Complete () n'a pas été exécuté, mais aucune garantie. .
la source