Який ефект мати занадто довго відкриту транзакцію в MSSQL?


11

Мені просто цікаво, що станеться, якщо ви розпочнете транзакцію в БД і забули її зробити або відкатати. Чи буде сервер вниз? Скажімо, ви залишили його на 3 дні.

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

Відповіді:


14

Наявність відкритої угоди сама по собі майже не матиме наслідків. Простий

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

, в гіршому випадку, буде містити кілька байт значень статусу. Нічого страшного.

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

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

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

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

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

Зміни даних записуються у файл журналу, як і блоки, які їх захищають. Їх неможливо видалити з журналу, поки транзакція не здійсниться. Отже, дуже довга транзакція може спричинити розрив файлу журналу з пов'язаними з ним проблемами.

Якщо в поточній роботі використовується tempdb, що, ймовірно, для великих навантажень, ресурси там можуть бути пов'язані до кінця транзакції. У крайньому випадку це може спричинити збій інших завдань, оскільки для них більше не вистачає місця. У мене були випадки, коли невміло закодований UPDATE заповнював tempdb, тому не вистачало диска для СОРТУВАННЯ звіту, і звіт не вдався.

Якщо ви вирішите ПОВЕРНУТИСЯ транзакції або система виходить з ладу та відновлюється, час, необхідний для того, щоб система знову стала доступною, залежатиме від того, скільки робіт було виконано. Просто відкриття транзакції не вплине на час відновлення, це скільки роботи виконано. Якщо транзакція була відкритою, але простоювати протягом години відновлення буде майже миттєво. Якщо він писав постійно протягом тієї години, головне правило полягає в тому, що час відновлення також буде близько години.

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

Не спокушайтеся переходити в іншу крайність і уникати транзакцій і блокувань цілком. Якщо вам потрібно підтримувати узгодженість даних (а чому б ви ще використовували базу даних?), Рівень ізоляції та транзакції служать дуже важливою метою. Дізнайтеся про свої варіанти та вирішіть, з яким балансом сумісності та правильності ви готові жити для кожної частини вашої заявки.


навіть якщо він відкритий три дні?
JanLeeYu

Так, навіть на три дні. Важливим моментом є обсяг роботи, яку було виконано під час відкриття TX, а не лише те, як довго він був відкритий. Звичайно, як DBA ви можете запитати у власника транзакції, чому вони потребують, щоб вона була відкрита так довго. Коли я керував командою DBA, я записав усі TX, які були відкритими більше 30 хвилин, і розмовляв з власником.
Майкл Грін

ГАРАЗД. Дякую за чудове пояснення. Хоча всі теж великі.
JanLeeYu

Яке полегшення ... Ще раз дякую за відповідь.
JanLeeYu

"Погане кодування ОНОВЛЕНО" Yup. Побачила це. Оператор оновлення всередині циклу, який не кваліфікував деякі імена та призвів до 1 = 1 подібної поведінки, тому оновив всю таблицю для кожної ітерації циклу (яка також містила неправильні дані і для більшості цих рядків).
jpmc26

6

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

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


наприклад, той, хто створив транзакцію, від’єднаний від сервера, чи зможе він знову ввійти на сервер, щоб закрити транзакцію?
JanLeeYu

Це залежатиме, якщо транзакція була в середовищі, яке використовувало MSDTC, це могло б бути сиротою. У такому випадку жоден користувач більше не зможе його закрити самостійно ... DBA повинен буде вступити, щоб впоратися з цим. Крім цього, ви, як правило, повинні бачити, що транзакція скасовується сервером SQL Server, коли він відключається ... але знову ж таки для великих транзакцій, що може бути не завжди.

Якщо це станеться, чи зможе адміністратор все-таки закрити транзакцію?
JanLeeYu

Я не можу відповісти на це, все залежить. У мене були випадки, коли сервер потрібно було перезапустити або екземпляр не вдався перейти на вторинний вузол / репліку.

4

Неповна транзакція може містити велику кількість блокувань і викликати блокування

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

джерело


наприклад, той, хто створив транзакцію, від’єднаний від сервера, чи зможе він знову ввійти на сервер, щоб закрити транзакцію?
JanLeeYu

Після того, як SQL Server знає, що з'єднання було втрачено, він поверне транзакцію. Дивіться тут dba.stackexchange.com/questions/47404 / ... . Якщо той самий користувач повторно підключиться, це буде інший сеанс, тому не можна якось "прийняти" стару транзакцію.
Майкл Грін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.