Я недавно выполнил запрос на обновление 100 000 записей. Я понял, что допустил ошибку, пока выполнялся запрос, и быстро отключил сетевой кабель.
Есть ли запрос на обновление?
- остановить обработку и полностью выполнить откат?
- продолжить обработку до завершения и зафиксировать?
- остановить обработку и оставить обновленной только часть целевых строк?
sql-server
network
Робокоп
источник
источник
Ответы:
Как упоминали Ник и Мартин, конечный статус вашего запроса зависит от того, знает ли SQL Server о подключении сетевого кабеля до завершения запроса. Из Books Online (хотя мне интересно, что существуют эквивалентные темы для этого в 2000 , 2005 , 2008 и 2008 R2 , но не 2012 или 2014):
(Кроме того, слово « соединения» во втором последнем предложении, вероятно, подразумевало транзакции . Я не знаю, как откатить соединение.)
Аналогичным образом, SQL Server может отменить или повторить транзакции во время восстановления после неожиданного выключения сервера, и это будет зависеть от состояния транзакции в момент завершения работы. Я видел, как люди использовали эту тактику, чтобы добиться того, что вы пытались сделать (отменить транзакцию (и)), и когда сервер снова запустился, большая часть работы была просто переделана (поэтому общий эффект от их реакции коленного рефлекса был намного ближе к нулю, чем они ожидали).
Поэтому вместо того, чтобы подвергаться этому, вместо того, чтобы совершать радикальные действия в панике, например, дергать сетевой кабель или выключать компьютер, я предлагаю в будущем улучшить дисциплину при выполнении специальных запросов для важных систем. Например, вместо:
Есть это:
Затем, если обновление действительно было правильным, вы можете выделить
COMMIT
деталь и запустить ее. Если это не так, вы можете спокойно выделитьROLLBACK
часть и запустить ее. Вы даже можете использовать надстройки, такие как SSMS Tools Pack, чтобы отредактироватьNew Query
шаблон, добавив этот шаблон.Теперь это может привести к проблемам в том случае, если вы выполните запрос, а затем не будете выполнять фиксацию или откат, потому что теперь ваша транзакция блокирует других пользователей. Но это лучше, чем безвозвратно модифицировать данные.
И, конечно, как всегда, есть резервная копия, на которую можно положиться.
источник
@ Аарон прав. Лучше всего создать транзакцию до того, как ваши команды. Если вы не можете вспомнить, что делать, то один из вариантов - войти в
Tools-Options
настройку и включитьSET IMPLICIT_TRANSACTIONS
. Это автоматически запустит транзакцию, как только будут выполнены определенные команды. Это включает в себяUPDATE
иDELETE
т. Д. Это, кажется, довольно полный список любой команды, которая будет"change"
что-то.SELECT
также включен в список иwill
начать транзакцию. Вы можете увидеть полный список команд , которые начинаются завещание транзакции этого параметр здесь . Он не будет создавать транзакцию, если она уже запущена. Теперь минусом этого является то, что вам придется помнить об этомCOMMIT
после внесения любых изменений.ПРИМЕЧАНИЕ: на основе предложения @ Аарона я собираюсь еще раз подчеркнуть это.
В основном вы торгуете, забывая
BEGIN
о транзакции, и что-то путаете, забываетеCOMMIT
о транзакции и зависаете, если оставляете ее открытой, а затем уходите на день. Я тестировал, просто закрывая окно запроса, думая, что он откатит мою транзакцию, однако он действительно подсказал мне, хочу ли я зафиксировать или откатить транзакцию.источник
SELECT
будет начать транзакцию (которая также документированный в ссылке вы публикуемую)я думаю, что это действительно зависит
если команда уже достигает сервера до того, как вы отсоедините сетевой кабель, она все равно будет продолжать выполняться в обычном режиме.
если у вас есть TransactionScope (используется в .Net, но не на других языках) для инкапсуляции всех команд обновления, вы, вероятно, можете остановить фиксацию транзакции только в том случае, если не выполнена транзакцияs.Somplete (), но без гарантии. ,
источник