Наявність відкритої угоди сама по собі майже не матиме наслідків. Простий
BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT
, в гіршому випадку, буде містити кілька байт значень статусу. Нічого страшного.
Більшість програм виконають фактичну роботу в рамках транзакції, і це інша справа. Суть угоди полягає в тому, що ви можете бути впевнені, що декілька фактів у базі даних є істинними одночасно, незважаючи на те, що інші користувачі одночасно пишуть у ту саму базу даних.
Візьмемо канонічний приклад переказу грошей між банківськими рахунками. Система повинна переконатися, що вихідний рахунок існує достатньо коштів, цільовий рахунок існує, а також як дебетовий, так і кредитний трапляються або не відбувається. Він повинен гарантувати це, поки трапляються інші транзакції, можливо навіть між цими двома рахунками. Система забезпечує це за допомогою блокування на відповідних таблицях. Які замки зроблені та яку роботу інших людей ви бачите, контролюється рівень ізоляції транзакцій .
Тож якщо ви багато працюєте, є велика ймовірність, що інші транзакції будуть чергатися на чергу, чекаючи об’єктів, на яких ви тримаєте блокування. Це зменшить загальну пропускну здатність системи. Врешті-решт вони потраплять до меж таймауту та виходять з ладу, що є проблемою для загальної поведінки системи. Якщо ви використовуєте оптимістичний рівень ізоляції, транзакція може закінчитися невдачею, якщо ви спробуєте скористатися через чужу роботу.
Тримання замків займає системні ресурси. Це пам'ять, яку система не може використовувати для обробки інших запитів, зменшуючи пропускну здатність.
Якщо було виконано багато робіт, система може обрати ескалацію блокування . Замість блокування окремих рядків вся таблиця буде заблокована. Тоді зачіпатимуть більше одночасних користувачів, пропускна здатність системи ще більше знизиться, а вплив додатків буде більшим.
Зміни даних записуються у файл журналу, як і блоки, які їх захищають. Їх неможливо видалити з журналу, поки транзакція не здійсниться. Отже, дуже довга транзакція може спричинити розрив файлу журналу з пов'язаними з ним проблемами.
Якщо в поточній роботі використовується tempdb, що, ймовірно, для великих навантажень, ресурси там можуть бути пов'язані до кінця транзакції. У крайньому випадку це може спричинити збій інших завдань, оскільки для них більше не вистачає місця. У мене були випадки, коли невміло закодований UPDATE заповнював tempdb, тому не вистачало диска для СОРТУВАННЯ звіту, і звіт не вдався.
Якщо ви вирішите ПОВЕРНУТИСЯ транзакції або система виходить з ладу та відновлюється, час, необхідний для того, щоб система знову стала доступною, залежатиме від того, скільки робіт було виконано. Просто відкриття транзакції не вплине на час відновлення, це скільки роботи виконано. Якщо транзакція була відкритою, але простоювати протягом години відновлення буде майже миттєво. Якщо він писав постійно протягом тієї години, головне правило полягає в тому, що час відновлення також буде близько години.
Як бачите, довгі транзакції можуть бути проблематичними. Для OLTP-систем найкращою практикою є здійснення однієї транзакції з базою даних на кожну бізнес-операцію. Для пакетного введення робочого процесу в блоки, з частими комісіями, і перезапуск логічно кодованої. Зазвичай декілька тисяч записів можуть бути оброблені всередині однієї транзакції БД, але це повинно бути перевірено на паралельність та відновлення споживання.
Не спокушайтеся переходити в іншу крайність і уникати транзакцій і блокувань цілком. Якщо вам потрібно підтримувати узгодженість даних (а чому б ви ще використовували базу даних?), Рівень ізоляції та транзакції служать дуже важливою метою. Дізнайтеся про свої варіанти та вирішіть, з яким балансом сумісності та правильності ви готові жити для кожної частини вашої заявки.