Felhasználói eszközök

Eszközök a webhelyen


mysql:my-10

10. ТРАНЗАКЦІЇ

Транзакції. Вимоги ACID

  • ACID: [A-atomicity (атомарність),
  • C-consistency (узгодженність),
  • I-isolation (ізоляція),
  • D-durability (надійність)].

Атомарність – транзакція неподільний єдиний блок.
Узгодженність – транзакція гарантує після її завершення узгодженність даних БД.
Ізоляція – транзакція виконується незалежно від інших транзакцій. Дані, оброблені транзакцією, стають доступними іншим тільки після її завершення.
Надійність – зміни, які були внесені транзакцією, не будуть втрачені навіть при збої системи.

Команди, що реалізують транзакції
Початок транзакції:

 START TRANSACTION; (або BEGIN WORK; або BEGIN;) 

Кінець транзакції:

  COMMIT; 		

Відкат:

  ROLLBACK;

Повернення в точку збереження:

  ROLLBACK TO SAVEPOINT;

Точки збереження:

   SAVEPOINT;

Управління виконанням транзакції
Режим автоматичної фіксації

 SET AUTOCOMMIT = 1;   -- Кожна команда – окрема транзакція. (задається по замовчуванню)
 SET AUTOCOMMIT = 0;    -- кінець транзакції – COMMIT; 

Завершення сеансу без COMMIT не фіксує результати. Це еквівалентно ROLLBACK, коли БД попадає в початковий стан сеансу.

Блокування в InnoDB
InnoDB фактично накладає блокування не на рядки даних, а на записи індексів. Блокування можна формувати по різному:

  • record lock — блокування запису індексу
  • gap lock — блокування проміжку між, до або після індексного запису
  • next-key lock — блокування запису індексу і проміжку перед ним.

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

Базові типи блокувань в InnoDB
Блокування на рівні рядків. В залежності від рівня ізоляції транзакції можуть блокуватись

  • рядки, які попали у результуючу таблицю, так і
  • всі рядки, які розглядались при пошуку.

Два базові типи блокувань:

  • shared lock — спільне блокування, яке дозволяє іншим транзакціям читати рядки і ставити таке ж сумісне блокування, але не дозволяє змінювати рядки або ставити виключне блокування.
  • exclusive lock — виключне блокування, забороняє іншим транзакціям блокувати рядки, а також може блокувати рядки як на запис, так і на читання в залежності від рівня ізоляції.

Блокування при виконанні SELECT, UPDATE і DELETE:

   SELECT… LOCK IN SHARE MODE

— блокує запис для тих рядків, які зчитуються.

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

  SELECT… FOR UPDATE

— блокує читання рядків, які зчитуються. Команда UPDATE ставить точно таке ж блокування, коли зчитує дані для обновлення.

В сценарії «зчитати → змінити → записати назад» паралельна транзакція між зчитуванням і записом може змінити дані, але ця зміна буде стерта після завершення цією транзакції.
LOCK IN SHARE MODE не дозволить вклинитись сусідній транзакції – вона буде в стані очікування.
В даному випадку блокування буде ставитись двічі (спочатку сумісне блокування при зчитуванні, потім виключне при записі. Так як блокувань всього два, то існує теоретичний шанс появі між ними третього блокування, що може викликати deadlock.
Відміна FOR UPDATE в тому, що воно зразу ставить виключне блокування, як в UPDATE. Тому для сценарію «зчитати → змінити → записати назад» блокування буде тільки один раз при зчитуванні, що зменшить імовірність появи deadlock.

Ізоляція транзакцій (від інших). Рівні ізоляцій.
Рівні ізоляції (РІ) визначають, як інші транзакції можуть «бачити» дані в активній транзакції. Модифікація рівня ізоляції транзакцій:

 SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL X;

X (рівень ізоляції) = READ UNCOMMITED | READ COMMITED | REPEATABLE READ (по замовчуванню) | SERIALIZABLE.
Для блокованого читання

 SELECT… FOR UPDATE/LOCK IN SHARE MODE, UPDATE і DELETE

блокування залежить від типу умови (WHERE):

  • якщо умова задає одне значення (WHERE id=6), то Record lock – блокується лише знайдений індексний запис.
  • якщо умова задає диапазон (пр. WHERE id > 6), то Gap lock (або next-key lock) – блокується весь диапазон.

1. Рівень ізоляції READ COMMITED

  • READ COMMITED –
    «читання, яке змінюється». Узгоджене читання без блокування, виконується з останнього снапшоту.

Снапшот (SnapShot) — миттєвий знімок, копія файлів та директорії файлової системи на певний момент часу.
Блокуюче читання (SELECT… FOR UPDATE/LOCK IN SHARE MODE), UPDATE і DELETE блокують тільки шукані індексні записи (record lock).
Тому можлива вставка паралельним потоком записів в проміжки між індексами. Проміжки блокуються (gap lock) тільки при перевірках зовнішніх ключів.
Блокування проглянутих рядків (record lock), які не задовільняють WHERE, знімаються зразу після їх обробки WHERE.

READ COMMITED:

 count=0    INSERT   count=1   COMMIT   count=1     (транзакція)
 ---------------------------------------------------------------
 count=0  транз.     count=0            count=1   (інша транз.)

2. Рівень ізоляції READ UNCOMMITED
READ UNCOMMITED – читання «брудних» даних (найслабший рівень ізоляції).
Всі запити SELECT читаються неблокованими. Зміни незавершенної транзакції можуть бути прочитані іншими транзакціями.
Ці зміни можуть бути ще відмінені (ROLLBACK). Це неузгоджене «брудне читання». В іншому виконується,як і при READ COMMITED.

READ UNCOMMITED:

 count=0   INSERT   count=1   ROLLBACK   count=0 (транзакція)
 --------------------------------------------------------------
 count=0  транз. count=0    count=1    count=0  (інша транз)

3. Рівень ізоляції REPEATABLE READ
REPEATABLE READ (значення по замовчуванню)
Узгоджене читання (SELECT) нічого не блокує, читає рядки з снапшоту, який створюється при першому читанні в транзакції. Однакові запити завжди дають однаковий результат. Транзакція «не бачить» зміни поки не завершиться. Для блокирующего читання (SELECT… FOR UPDATE/LOCK IN SHARE MODE), UPDATE і DELETE блокування залежить від умови(WHERE):

  • Record lock – якщо умова задає одне значення (пр. WHERE id=6), то блокується лише знайдений індексний запис.
  • Gap lock (або next-key lock) – якщо умова задає диапазон (пр. WHERE id > 6), то блокується весь диапазон.
 count=0  INSERT   count=1   COMMIT   count=1  (транзакція)
 -----------------------------------------------------------
 count=0  транз.  count=0     count=0 COMMIT    count=0

4. Рівень ізоляції SERIALIZABLE
SERIALIZABLE (найбільш надійний рівень, що досягається за рахунок зменшення швидкості).
Він подібний до REPEATABLE READ, за виключенням одного моменту.
Якщо autocommit виключений (а при явному старті транзакції він включений), то всі прості запити SELECT неявно перетврорюються в SELECT… LOCK IN SHARE MODE,
якщо autocommit включений, то кожний SELECT виконується, як окрема транзакція. Використовується, як правило, для того, щоб перетворити всі запити читання в SELECT… LOCK IN SHARE MODE, якщо це не можна зробити в коді додатку.

count=0 INSERT count=1 COMMIT count=1 (транзакція)


count=0 транз. count=?(очікування) count=1 COMMIT count=0

Блокування в MyISAM – спрощена транзакція
В MySQL можна блокувати

  • Таблиці
  • Сторінки
  • рядки.

Для типу MyISAM можна блокувати тільки всю таблицю:

 LOCK TABLE таблиця  READ;
 LOCK TABLES таблиця_1 READ, таблиця_2  WRITE;

Блокування READ (режим «тільки для читання»)– всі потоки (клієнти) можуть лише читати рядки із заблокованої таблиці.
Блокування WRITE (монопольний режим) – лише один потік може читати і модифікувати таблицю. Інші – не мають доступу, і очікують зняття блокування UNLOCK.
Зняття блокування –

 UNLOCK TABLES;
mysql/my-10.txt · Utolsó módosítás: 2021/08/14 13:33 szerkesztette: holovacs