Чи погана практика завжди створювати транзакцію?


88

Чи погана практика завжди створювати транзакцію?

Наприклад, це вдала практика створити транзакцію не тільки для однієї простої SELECT?

Яка вартість створення транзакції, коли вона насправді не потрібна?

Навіть якщо ви використовуєте такий рівень ізоляції, як READ UNCOMMITTEDце погана практика?


1
Якщо дивитися на вплив BEGIN TRAN SELECT ... COMMITvs, SELECTто, мабуть, є надзвичайно незначна різниця у продуктивності.
Мартін Сміт

Відповіді:


100

Чи погана практика створювати транзакцію завжди?

Це залежить від того, в якому контексті ви тут говорите. Якщо це оновлення, я б дуже рекомендував явно використовувати TRANSACTIONS. Якщо це ВИБІР, то НІ (явно).

Але зачекайте, що спочатку потрібно зрозуміти: все на сервері sql міститься в транзакції.

Коли варіант сеансу IMPLICIT_TRANSACTIONSє, OFFі ви явно вказуєте, begin tranі commit/rollbackтоді це зазвичай відомо як Явна транзакція . В іншому випадку ви отримаєте транзакцію з автоматичним дорученням.

Коли IMPLICIT_TRANSACTIONSце неявна транзакція автоматично запускається при виконанні одного з типів операторів , зареєстрованих в книгах онлайн статті (наприклад , / / ) , і воно повинно бути абсолютно чи відкату в явному вигляді. Виконання в цьому режимі збільшить і розпочнеть іншу "вкладену" транзакцію)ONSELECTUPDATECREATEBEGIN TRAN@@TRANCOUNT

Щоб переключитися, в якому режимі ви перебуваєте, ви використовуєте

SET IMPLICIT_TRANSACTIONS ON

або

SET IMPLICIT_TRANSACTIONS OFF

select @@OPTIONS & 2

якщо вище повертає 2, ви перебуваєте в неявному режимі транзакцій. Якщо він поверне 0, ви перебуваєте в автокомісії.

скільки коштує створення транзакції, коли насправді це не потрібно?

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

Навіть якщо ви використовуєте рівень ізоляції read_uncomitted. Це погана практика? тому що у нього не повинно виникнути проблем із блокуванням.

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

Ви можете використовувати це на рівні з'єднання / запиту, щоб це не впливало на інші запити.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Знайшла цікаву статтю Джеффа Етвуда, що описує тупики через головоломку «Філософи», а також описує рівень ізоляції, зробленого на знімку .

Редагувати:

З цікавості я здійснив тест, вимірюючи вплив на T-журнал за допомогою лічильників Perfmon, таких як Log Bytes Flushed / Sec, Log Flush Waits / Sec (кількість комітетів в секунду, які чекають, коли відбудеться вмивання LOG), як показано нижче на графіку:

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

зразок коду:

create table testTran (id int, Name varchar(8))
go

-- 19 sec
-- Autocommit transaction
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
---------------------------------------------------
-- 2 sec
-- Implicit transaction
SET IMPLICIT_TRANSACTIONS ON
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
COMMIT;
SET IMPLICIT_TRANSACTIONS OFF


----------------------------------------------------
-- 2 sec
-- Explicit transaction
declare @i int
set @i = 0
BEGIN TRAN
WHILE @i < 100000
Begin
INSERT INTO testTran values (1,'Kin Shah')
set @i = @i+1
End
COMMIT TRAN

Автокомісійні транзакції : (Відредаговано як підкреслено @TravisGan)

  • Вставка зайняла 19 секунд.
  • Кожна автокомісія передасть буфер T-журналу на диск через автокоміту (після виділення @TravisGan, і я це пропустив).
  • Процес CHECKPOINT завершиться швидко, оскільки кількість брудного буфера журналу, необхідного для промивання, буде меншим, оскільки він працює тихо.

ІМПЛІКТ І явна транзакція:

  • Вставка зайняла 2 секунди.
  • Для транзакцій EXPLICIT буфери журналів будуть видалятися лише тоді, коли вони заповнені.
  • На відміну від транзакції Autocommit, в транзакції EXPLICIT процес CHECKPOINT триватиме більше тривалості, оскільки у нього буде більше буферів журналів для розмивання (пам’ятайте, що буфери журналів видаляються лише тоді, коли вони заповнені).

Існує DMV sys.dm_tran_database_transaction, який поверне інформацію про транзакції на рівні бази даних.

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

З вищенаведених тестів, між імпліцитними та явними транзакціями майже немає різниці.

Дякуємо @TravisGan за те, що він допоміг додати більше відповідей.


35

Оператор SQL завжди працює в транзакції. Якщо ви не запускаєте його явно, кожен оператор SQL запускається в транзакції.

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


1

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.