Deadlock при оновленні

Дві транзакції, ще не завершилися, але, що намагаються поновити одні й ті-ж
запису, вважаються конкуруючими. Існує два режими обробки deadlock –
wait і no wait (з очікуванням і без очікування). У BDE для будь-яких транзакцій IB
використовується режим без очікування, і режим з очікуванням можна встановити тільки при
прямий працювати з IB API (наприклад через FreeIBComponents).

"Невдачливих", природно, вважається транзакція, яка отримала повідомлення про
deadlock. Це означає, що одне з дій, що проводяться в транзакції, не може
бути виконано. Отже, така транзакція повинна бути скасована (rollback).
Слід уникати тривалих транзакцій, які можуть потрапити в таку ситуацію –
єдиним виходом з неї буде спроба почати транзакцію знову і повторити
всі дії.

Зменшити число можливих конфліктів оновлення можна скоротивши брешемо
виконання транзакції. Наприклад, спочатку приймаються дані від користувача, і
якщо він підтверджує введену інформацію, додаток стартує транзакцію,
швидко передає дані на сервер, і завершується. Чим швидше пройде транзакція,
тим більше у неї шансів завершитися успішно. Саме для цього в BDE 3.x був
введений режим Cached Updates (кешовані зміни). При Cached Updates
зміни накопичуються на клієнтської частини програми, потім при виклику методу
ApplyUpdates зміни "вистрілюють" на сервер. У будь-якому випадку, навіть якщо ви
не можете позбавитися від тривалих оновлюють транзакцій, потрібно продумати
логіку програми і обов'язково передбачати в додатку обробку
виникаючих конфліктів.

Deadlock при читанні


Всі описувані нижче проблеми виправлені в BDE 4.01. При цьому параметр
DRIVER FLAGS вказувати не потрібно.

Deadlock при читанні виникає в основному в SQL-серверах, які використовують
сторінкові блокування при читанні або модифікації даних (MS SQL і Sybase).
Здається дивним, що при роботі з IB, в якому блокування взагалі відсутні
(Конфлікт поновлення блокуванням не рахується – це не блокування а саме
конфлікт), іноді все-таки виникає deadlock при читанні даних.

Причина ось у чому: транзакції рівня ізоляції Read Committed мають в IB два
режиму – NO RECORD VERSION і RECORD VERSION. У першому випадку, якщо при читанні
запису ядро IB виявляє наявність непідтвердженою (uncommitted) версії цієї
запису, то повертає повідомлення про deadlock. Це як-би сигналізує додатком,
що скоро ця запис можливо буде оновлено (адже в ReadCommitted чужі
зміни будуть помітні відразу після їх підтвердження (commit)). У режимі RECORD
VERSION наявність непідтверджених версій записів ігнорується, і завжди
повертається стара версія запису.

Здавалося-б, так чому-б BDE не працювати за замовчуванням у режимі RECORD
VERSION? На жаль, так спочатку було закладено – транзакція Read Committed
в BDE запускається з параметром NO RECORD VERSION – але до версії Delphi 2.0 цього
незручності майже ніхто не помітив. А от чому не помітили, читаємо далі.

Рівень ізоляції в AUTOCOMMIT в різних версіях BDE


Залежно від версії BDE змінювалися рівні ізоляції за замовчуванням. Коли ви
явно не використовуєте методи управління транзакціями (Database.StartTransaction,
Commit і Rollback), то за вас це робить BDE. Не вірите? Подивіться в SQL
Monitor. Найголовніше, що тип транзакції за замовчуванням "зашитий" в SQL Link. І
навіть якщо ви помістили на форму компонент TDatabase, і змінили у нього властивість
tiTransIsolation, то це не впливає на BDE, поки ви не викличете метод
Database.StartTransaction.

Отже, які-ж транзакції стартує за замовчуванням BDE?


Отже, deadlock-і при читанні помітили тільки в Delphi 2.0, саме тому що
транзакція за замовчуванням змінилася на Read Committed. До речі, в READLINK.TXT для
Delphi 2.x і 3.0 написано, що якщо потрібно змінити транзакцію за замовчуванням на
Repeatable Read, то слід встановити в параметрах драйвера DRIVER FLAGS = 512.
Тобто фактично "забезпечити сумісність" поведінки додатків, перенесених у
Delphi 2 з Delphi 1.

! Не встановлюйте DRIVER FLAGS не прочитавши попередньо READLINK.TXT.
Справа в тому, що наприклад у версії 4.0 кількість прапорів збільшилася:

Схожі статті:


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

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*