Чи відключення мережі зупиняє запит?


13

Нещодавно я виконав запит на оновлення до 100 000 записів. Я зрозумів, що помилився під час запуску запиту і швидко відключив мережевий кабель.

Чи запит оновлення

  1. припинити обробку та повністю відкати?
  2. продовжувати обробку до завершення і виконувати?
  3. припинити обробку та залишити оновлену лише частину цільових рядків?

2
Як тільки запит потрапить на сервер, він продовжиться, якщо ви не скасували запит на сервері.
JP Chauhan


1
Коментар Мартіна дає пряму відповідь на ваше запитання, робокоп. Якщо мережа сповістить SQL Server про відключення до завершення запуску запиту, SQL Server поверне його назад. В іншому випадку, якщо запит буде завершений до того, як SQL Server повідомить, що відбувся відключення мережі, він буде здійснений. Ні в якому разі (якщо ви написали єдиний запит на оновлення) SQL Server не виконає часткового оновлення.
Нік Чаммас

Відповіді:


22

Як згадували Нік та Мартін, можливий стан вашого запиту залежить від того, чи знає SQL Server про підключення мережевого кабелю до завершення запиту. З книг Інтернет (хоча мені здається цікавим, що для цього є рівнозначні теми у 2000 , 2005 , 2008 та 2008 рр. , Але не 2012 чи 2014 рр.):

Якщо помилка перешкоджає успішному завершенню транзакції, SQL Server автоматично відкочує транзакцію та звільняє всі ресурси, що містяться в транзакції. Якщо мережеве підключення клієнта до екземпляра двигуна бази даних порушено, будь-які невирішені транзакції для з'єднання будуть відмовлені, коли мережа повідомляє про примірник розриву. Якщо клієнтська програма виходить з ладу або якщо клієнтський комп'ютер виходить з ладу або перезапускається, це також розриває з'єднання, і екземпляр Двигуна баз даних скасовує будь-які непогашені з'єднання, коли мережа повідомляє його про перерву. Якщо клієнт виходить із програми, будь-які непогашені транзакції повертаються назад.

(До речі, що слово з'єднання в 2 - м останньому реченні, ймовірно , мав в виду, що операції . Я не знаю , як один відкочується з'єднання.)

Аналогічним чином SQL Server може скасувати або повторити транзакції під час відновлення після несподіваного вимкнення сервера, і це залежатиме від стану транзакції в момент відключення. Я бачив, як люди використовують цю тактику, щоб досягти того, що ви намагалися зробити (скасувати транзакцію), і коли сервер запустився знову, значна частина роботи була просто перероблена (тому чистий ефект від їхньої реакції на коліна був набагато ближчим до нуля, ніж вони очікували).

Тож замість того, щоб піддаватися цьому, замість того, щоб робити серйозні речі в паніці, як, наприклад, потріскувати мережевий кабель чи вимикати машину, я пропоную вам у майбутньому вдосконалити дисципліну щодо запуску спеціальних запитів щодо важливих систем. Наприклад, замість:

UPDATE dbo.sometable 
-- where *oops* I forgot this part

Майте це:

BEGIN TRANSACTION;

UPDATE dbo.sometable
-- where *oops* I forgot this part

-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;

Потім, якщо оновлення було дійсно правильним, ви можете виділити його COMMITчастину та запустити її. Якщо це не так, ви можете спокійно виділити ROLLBACKдеталь і запустити її. Ви навіть можете використовувати надбудови, такі як пакет SSMS Tools, щоб редагувати ваш New Queryшаблон, щоб включити цю коробку.

Тепер це все ще може зашкодити вам у випадку, якщо ви запустите запит, а потім не виконуватимете жодних зобов'язань або відкату, оскільки тепер ваша транзакція блокує інших користувачів. Але це краще, ніж безповоротно змінювати дані.

І звичайно, як завжди, є резервна копія, на яку можна покластися.


5
Це чудова порада і стосується корінь проблеми ОП, але насправді не відповідає на питання, чи продовжував запит працювати чи ні.
Nick Chammas

3
Дякую @Nick, моя мотивація полягала в тому, щоб вирішити причину (що спонукало питання), а не симптом, але я оновив свою відповідь.
Аарон Бертран

8

@Aaron правильний. Створення транзакції перед командами - найкраща ставка. Якщо ви не можете пам'ятати, що робити це, один із варіантів - зайти в Tools-Optionsналаштування та включити SET IMPLICIT_TRANSACTIONS. Це автоматично запустить транзакцію, як тільки будуть виконані певні команди. Це включає в себе UPDATEі DELETEт. Д. Це, здається, досить повний перелік будь-якої команди, яка б "change"щось робила. SELECTтакож включається до списку та willрозпочинає транзакцію. Ви можете побачити повний список команд , які починаються заповіт транзакції цього параметр тут . Він не створить транзакцію, якщо її вже запущено. Тепер суть цього полягає в тому, що вам доведеться пам’ятати COMMITпісля будь-яких змін.

ПРИМІТКА. На підставі пропозиції @ Аарона я хочу ще раз наголосити на цьому.

This is very important!  You will have to remember to COMMIT after any change made!

В основному ви торгуєте, забувши BEGINтранзакцію і щось зіпсували, забувши COMMITпро транзакцію і повісили її, якщо залишити її відкритою, а потім залишити на день. Я тестував лише закриття вікна запиту, думаючи, що це відкатить мою транзакцію, однак це підказало мені, якщо я хочу здійснити або відмовити транзакцію.

введіть тут опис зображення


На насправді: SELECT буде почати транзакцію (яка також документований на засланні ви опубліковану)
a_horse_with_no_name

Дякуємо @a_horse_with_no_name за те, що це зрозумів! Я не читав достатньо уважно і відходив від старої пам’яті (це явно було неправильно).
Кеннет Фішер

1
Це корисна публікація, але вона насправді не відповідає на питання ОП про те, чи продовжував роботу запит чи ні.
Нік Чаммас

2
Це означало як доповнення до відповіді @ Аарона. Це було просто багато для коментаря.
Кеннет Фішер

2

я думаю, це дійсно залежить:

якщо команда вже доходить до сервера до відключення мережевого кабелю, команда продовжує виконуватись нормально.

якщо у вас є TransactionScope (використовується в .Net, не впевнений, що в інших мовах) для інкапсуляції всіх команд оновлення, ви, ймовірно, можете зупинити здійснення транзакції лише в тому випадку, якщо transakScope.Complete () не виконано, але немає гарантії. .


2
Ви сказали: "Якщо команда вже доходить до сервера, перш ніж ви відключите мережевий кабель, команда продовжує виконуватись нормально". Цьому суперечить сторінка BOL SQL Server, яку Мартін посилав вище. Див. "Помилки під час обробки транзакцій" .
Nick Chammas

ти правий. із вказаною транзакцією, команда відкатується автоматично. але, як ми відчували, коли жодна транзакція не була визначена явно, команда (пакетне оновлення без транзакції) була виконана повністю, навіть ми зупинили нашу програму в середині, що насправді порушило з'єднання - але це насправді не хороший приклад, як терміни мабуть, невірно. Мабуть, це добре зробити для цього тестування
Rex
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.