Відношення рівнів ізоляції транзакцій із блокуваннями на столі


105

Я прочитав про 4 рівні ізоляції:

Isolation Level       Dirty Read    Nonrepeatable Read  Phantom Read  
READ UNCOMMITTED      Permitted       Permitted           Permitted
READ COMMITTED              --        Permitted           Permitted
REPEATABLE READ             --             --             Permitted
SERIALIZABLE                --             --              --

Я хочу зрозуміти блокування кожної ізоляції транзакцій, що займає таблиця

READ UNCOMMITTED - no lock on table
READ COMMITTED - lock on committed data
REPEATABLE READ - lock on block of sql(which is selected by using select query)
SERIALIZABLE - lock on full table(on which Select query is fired)

нижче - три явища, які можуть статися при ізоляції транзакцій
Брудне читання - відсутність блокування
Неповторне читання - не брудне читання як блокування за скоєними даними
Phantom Read - блокування блоку sql (яке вибирається за допомогою вибору запиту)

Я хочу зрозуміти, де ми визначаємо ці рівні ізоляції: лише на рівні jdbc / hibernate або в DB

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


3
Це повністю залежить від бази даних. Різні БД можуть використовувати різні алгоритми для рівня ізоляції. Деякі можуть використовувати MVCC (без блокування у вибраних запитах), інші використовують жорстке двофазне блокування (спільні та ексклюзивні блокування).
брб чай

Відповіді:


157

Я хочу зрозуміти блокування кожної ізоляції транзакцій, що займає таблиця

Наприклад, у вас є три одночасні процеси A, B і C. A запускає транзакцію, записує дані і здійснює фіксацію / відкат (залежно від результатів). B просто виконує SELECTзаяву для читання даних. C читає та оновлює дані. Усі ці процеси працюють на одній таблиці Т.

  • ЧИТАЙТЕ НЕЗАБАВЛЕНО - на столі немає блокування. Ви можете читати дані в таблиці під час написання на ній. Це означає, що A записує дані (не передано), а B може прочитати ці не передані дані та використовувати їх (для будь-яких цілей). Якщо A виконує відкат, B все ще прочитав дані та використав їх. Це найшвидший, але найнебезпечніший спосіб роботи з даними, оскільки це може призвести до відкриття даних у фізично не пов’язаних таблицях (так, дві таблиці можуть бути логічно, але фізично не пов’язані між собою в реальних додатках = \).
  • ЧИТАТИ ЗВ'ЯЗАНО - заблокувати введені дані. Ви можете прочитати дані, які були лише скоєні. Це означає, що A записує дані, а B не може прочитати дані, збережені A, доки A не виконає фіксацію. Проблема тут полягає в тому, що C може оновлювати дані, які були прочитані та використані на B і B клієнті, не буде оновлених даних.
  • REPEATABLE READ - блокування на блоці SQL (який вибирається за допомогою вибору запиту). Це означає, що B зчитує дані за певної умови, тобто WHERE aField > 10 AND aField < 20A вставляє дані, де aFieldзначення становить від 10 до 20, потім B знову читає дані і отримує інший результат.
  • СЕРІАЛІЗАБІЛЬНІ - блокування на повній таблиці (на яку запущено запит Select). Це означає, що B зчитує дані, і жодна інша транзакція не може змінювати дані в таблиці. Це найбезпечніший, але найповільніший спосіб роботи з даними. Крім того, оскільки проста операція читання блокує таблицю , це може призвести до великих проблем на виробництві: уявіть, що таблиця T - це таблиця рахунків-фактур, користувач X хоче знати рахунки за день, а користувач Y хоче створити новий рахунок-фактуру, тому в той час як X виконує зчитування рахунків-фактур, Y не може додати новий рахунок-фактуру (а коли мова йде про гроші, люди дійсно зліють, особливо начальство).

Я хочу зрозуміти, де ми визначаємо ці рівні ізоляції: лише на рівні JDBC / сплячого режиму або також у БД

Використовуючи JDBC, ви визначаєте його за допомогою Connection#setTransactionIsolation.

Використання сплячого режиму:

<property name="hibernate.connection.isolation">2</property>

Де

  • 1: ЧИТАЙТЕ НЕЗАБАВЛЕНО
  • 2: ЧИТАТИ ЗВ'ЯЗАНО
  • 4: ПОВТОРЕННЕ ЧИТАННЯ
  • 8: СЕРІАЛІЗАЛЬНІ

Конфігурація сплячки взята звідси (вибачте, це іспанською мовою).

До речі, ви можете встановити рівень ізоляції і на RDBMS:

і на, і на ...


docs.oracle.com/cd/B12037_01/server.101/b10743/consist.htm Просто для додання для Oracle: Можна встановити рівень ізоляції транзакції, використовуючи одне з цих висловлювань на початку транзакції: Встановити ІЗОЛЯЦІЮ ТРАНЗАЦІЇ РІВЕНЬ ЧИТАТИ ЗВ'ЯЗАНО; НАСТРОЙКА РІВНЯ ІЗОЛЯЦІЇ ТРАНЗАКЦІЇ СЕРІАЛІЗАЦІЙНО; Встановити транзакцію ЧИТАТИ ТІЛЬКИ;
Учень

2
Крім того, щоб заощадити витрати на мережу та обробку початку кожної транзакції оператором SET TRANSACTION, ви можете використовувати оператор ALTER SESSION для встановлення рівня ізоляції транзакцій для всіх наступних транзакцій: ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE; АЛЬТЕР СЕСІЙСЬКИЙ НАСТРОЙКИ ІЗОЛЯЦІЯ_LEVEL ЧИТАТИ ЗВ'ЯЗАНО;
Учень

12
Щодо повторного читання - я вважаю, що кращим прикладом для його демонстрації є такий: B починає транзакцію, читає дані на блоці sql WHERE aField> 10 AND aField <20, що дані блокуються до завершення транзакції. A намагається оновити ці дані, але чекає через блокування. Тепер, коли B знову прочитає ці дані в тій же транзакції, гарантовано буде читати ті самі дані, оскільки вони заблоковані. Виправте мене, якщо я помиляюся.
BornToCode

1
@LuiggiMendoza Як загальна концепція, рівні ізоляції - це приблизно брудні читання , не повторювані читання та фантомні рядки . Locks (S2PL) або MVCC - це реалізація для різних постачальників.
брб чай

4
@LuiggiMendoza - Я не був точним, він повинен бути таким - дані, які B читав, не змінюються, але послідовні вибірки, зроблені B, можуть повернути більше рядків. Це тому, що A не може змінювати рядки, які B вже читав , доки A не випустить їх. Однак A може вставити нові рядки, які визначають умову where (і тому наступного разу, коли A виконає вибір, він отримає інший результат із більшою кількістю рядків - фантомним зчитуванням).
BornToCode

9

Як говорить brb tea, залежить від реалізації бази даних та алгоритму, який вони використовують: MVCC або Two Phase Locking.

CUBRID (з відкритим кодом RDBMS) пояснює ідею цих двох алгоритмів:

  • Двофазна блокування (2PL)

Перший - коли транзакція T2 намагається змінити запис A, вона знає, що транзакція T1 вже змінила запис A і чекає, поки транзакція T1 буде завершена, оскільки транзакція T2 не може знати, чи буде транзакція T1 здійснена або прокатана. назад. Цей метод називається двофазним блокуванням (2PL).

  • Багатоверсійний контроль сумісності (MVCC)

Інший - дозволити кожному з них, транзакціям T1 і T2, мати власні змінені версії. Навіть коли транзакція T1 змінила запис A з 1 на 2, транзакція T1 залишає початкове значення 1 таким, яким він є, і пише, що версія транзакції T1 запису A дорівнює 2. Потім наступна транзакція T2 змінює запис A від 1 до 3, а не від 2 до 4, і пише, що версія транзакції T2 запису A дорівнює 3.

Коли транзакція T1 відкочується, не має значення, чи 2, версія транзакції T1, не застосовується до запису A. Після цього, якщо транзакція T2 здійснена, версія 3 транзакції T2 буде застосована до запису A. Якщо транзакція T1 здійснена до транзакції T2, запис A змінюється на 2, а потім на 3 під час здійснення транзакції T2. Остаточний стан бази даних ідентичний статусу виконання кожної транзакції незалежно, без впливу на інші транзакції. Тому він задовольняє властивість ACID. Цей метод називається багатоверсійним контролем одночасності (MVCC).

MVCC дозволяє проводити одночасні модифікації за рахунок збільшення накладних витрат у пам'яті (оскільки він повинен підтримувати різні версії одних і тих же даних) та обчислення (на рівні REPETEABLE_READ ви не можете втратити оновлення, тому він повинен перевіряти версії даних, наприклад Hiberate робить із блокуванням Optimistick Locking ).

У рівнях ізоляції транзакцій 2PL контролюються наступні :

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

  • Як довго тримаються зачитувані блоки.

  • Будь операція читання, що посилається на рядки, змінені іншою транзакцією:

    • Блокуйте, поки не буде звільнений ексклюзивний замок ряду.

    • Отримайте скоєну версію рядка, яка існувала на момент початку заяви або транзакції.

    • Прочитайте неспроможну модифікацію даних.

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

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

Конкретні приклади зв'язку між блокуваннями та рівнями ізоляції в SQL Server (використовуйте 2PL, за винятком READ_COMMITED з READ_COMMITTED_SNAPSHOT = ON)

  • READ_UNCOMMITED: не видайте спільні блокування, щоб запобігти іншим транзакціям змінювати дані, прочитані поточною транзакцією. ЧИТАЙТЕ НЕЗАБАВЛЕННІ транзакції також не блокуються ексклюзивними блокуваннями, які заважають поточній транзакції читати рядки, які були змінені, але не вчинені іншими транзакціями. [...]

  • READ_COMMITED:

    • Якщо для параметра READ_COMMITTED_SNAPSHOT встановлено значення OFF (за замовчуванням): використовуються спільні блокування для запобігання зміни інших рядків транзакцій під час виконання поточної транзакції. Спільні блокування також блокують оператор з читання рядків, модифікованих іншими транзакціями, поки інша транзакція не буде завершена. [...] Блокування рядків звільняється до обробки наступного рядка. [...]
    • Якщо для параметра READ_COMMITTED_SNAPSHOT встановлено значення УВІМКНЕНО, двигун баз даних використовує версію рядків, щоб представити кожному оператору транзакційно послідовний знімок даних, як він існував на початку оператора. Блоки не використовуються для захисту даних від оновлень іншими транзакціями.
  • REPETEABLE_READ: Спільні блокування розміщуються на всіх даних, прочитаних кожним оператором транзакції, і зберігаються до завершення транзакції.

  • СЕРІАЛІЗАЦІЙНІ: Блокування діапазону розміщується в діапазоні ключових значень, що відповідають умовам пошуку кожного оператора, виконаного в транзакції. [...] Блокування діапазону зберігається до завершення транзакції.


5

Замки завжди приймаються на рівні БД: -

Офіційний документ Oracle: - Щоб уникнути конфліктів під час транзакції, СУБД використовує блокування, механізми для блокування доступу інших до даних, до яких здійснюється транзакція. (Зверніть увагу, що в режимі автоматичного фіксації, коли кожне висловлення є транзакцією, блокування проводиться лише для одного оператора.) Після встановлення блокування воно залишається в силі, поки транзакція не буде здійснена або скасована назад. Наприклад, СУБД може заблокувати рядок таблиці, поки не буде здійснено оновлення до неї. Ефект цього блокування полягатиме в тому, щоб користувач не забруднив читання, тобто прочитав значення до того, як воно стане постійним. (Доступ до оновленого значення, яке не було здійснено, вважається брудним зчитуванням, оскільки можливо повернення цього значення до його попереднього значення. Якщо ви прочитаєте значення, яке згодом повернеться назад, ви прочитаєте недійсне значення. )

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

Одним із прикладів рівня ізоляції транзакцій є TRANSACTION_READ_COMMITTED, який не дозволить отримати доступ до значення, поки воно не буде здійснено. Іншими словами, якщо рівень ізоляції транзакцій встановлений на TRANSACTION_READ_COMMITTED, СУБД не дозволяє проводити брудні зчитування. Інтерфейс Connection включає п'ять значень, які представляють рівні ізоляції транзакцій, які ви можете використовувати в JDBC.

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