Яка точна залежність між транзакцією бази даних та блокуванням?


16

Це скромне запитання, задане в дусі підвищення моїх знань; будьте ласкаві у своїй відповіді.

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

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

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

Тобто мені здається, що для того, щоб транзакція була атомною та ізольованою, вона повинна робити певну блокування. Чи це ініційоване транзакцією приховане блокування того ж типу блокування, до якого різні бази даних дозволяють мені отримати доступ через такі конструкції, як SELECT FOR UPDATEявні LOCKкоманди? Або ці два поняття абсолютно різні?

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

Відповіді:


12

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

Так. Якщо це не відповідає дійсності, то ваше власне «блокування» було б застосовано лише до інших подібних «блокувань» і не взаємоділо б із власним блокуванням двигуна. Таким чином, ви б заблокували рядок у таблиці, щоб інша програма не була заблокована таким же чином, але ваш замок ігнорував би сам двигун. Ці семантики рідко бажані. Більшість випадків програма, що блокує рядок, означає "заблокувати її проти будь-яких засобів доступу / зміни". Сторона зауважила, що механізми блокування, які суворо застосовуються , є, оскільки вони корисні. Наприклад, SQL Server має блокування програм .

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

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

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


Можливо, ви можете додати про (без блокування) оптимістичний контроль паралельності
ypercubeᵀᴹ

Ага! Зараз ми говоримо. Справді, в моїй душі ховався MVCC . Дякую за чітко сформульовану відповідь, чудові довідники та те, що знайшли час, щоб справді розібратися з моїм запитанням.
Лаїрд Нельсон

3

Деякі відомості, перш ніж відповісти на ваші запитання:

Примітка. Це стосується Microsoft SQL Server - RDBMS ........

  • Дуже просто кажучи, транзакція - це послідовність робіт, яка повинна бути виконана у вигляді єдиної логічної одиниці у повному обсязі і повинна підтримувати властивості ACID.
  • Будь-яка RDBMS повинна надавати "Блокування засобів", які можна використовувати для завершення транзакції в повному обсязі, зберігаючи ізоляцію транзакції та її тривалість. Це забезпечує фізичну цілісність бази даних.
  • Найголовніше - за замовчуванням - транзакції управляються на рівні з'єднання. Отже, коли транзакція починається на з'єднанні, всі оператори T-SQL (S / I / U / D), виконані на цьому з'єднанні, є частиною транзакції до завершення транзакції. ( MARS обробляється по-різному)

Тепер повернемося до своїх питань:

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

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

Від BOL: Блокування та версії версій забороняють користувачам читати недозволені дані та заважають декільком користувачам одночасно намагатися змінювати одні й ті самі дані. Без блокування чи версійної версії запити, виконані проти цих даних, можуть призвести до несподіваних результатів, повертаючи дані, які ще не здійснені в базі даних.

Чи ініційована цією транзакцією, прихована транзакцією однакова блокування, до якої різні бази даних дозволяють отримати доступ через такі конструкції, як SELECT FOR UPDATE або явні команди LOCK?

Все на сервері sql міститься в транзакції. Коли Ви отримуєте доступ до своїх даних, RDBMS повинен робити блокування залежно від рівня ізоляції та операцій, які Ви виконуєте над Вашими даними. Перевірте цю відповідь для отримання більш детальної інформації.

Кілька хороших посилань:


2

Я б сказав, що транзакції є частиною "інтерфейсу" бази даних, в тому сенсі, що ви як розробник вирішуєте, коли почати, закінчити, що робити в межах транзакцій і т. Д. Блоки, як я бачу, належать до деталей реалізації і використовується для синхронізації доступу до різних об'єктів. У більшості випадків двигун сам вирішує, що і на який час його потрібно заблокувати. Існує багато блокувань системного рівня, якими не можна керувати безпосередньо (наприклад, двигун може блокувати певні області пам'яті). Навіть коли мова йде про блоки DML, багато з них трапляються поза сценою (наприклад, для забезпечення референтної цілісності Oracle і, наскільки я пам’ятаю, SQLServer може поставити блокування у відповідний рядок у головній таблиці, якщо нова запис буде вставлена ​​в таблиця деталей) в результаті операторів DML, виданих в рамках транзакції.

Що стосується транзакцій, ви можете очікувати більш-менш послідовної поведінки від будь-якої RDMS, яка стверджує, що відповідає транзакціям SQL та підтримці, але якщо мова йде про блокування, майже кожен постачальник використовує різну стратегію та термінологію. Наскільки я можу сказати, загальною частиною всіх RMDS є те, що сумісність між транзакціями визначається рівнем ізоляції, тоді як паралельність між блокуванням контролюється типами блокування (спільними, ексклюзивними тощо).

Підводячи підсумок, замки - це механізм низького рівня для контролю узгодженості об'єктів та одночасності. Блоки можуть видаватися під час виконання операторів SQL. Залежно від реалізації рівня ізоляції транзакцій, двигун може ставити різні типи блокувань на уражені об’єкти (рядки, групи рядків, індекси тощо). Існує обмежена кількість команд для видачі блокування вручну ( SELECT FOR UPDATE, LOCK). Блокування DML можна нарощувати (залежить від RDMS, наприклад, у рядку SQLServer-> сторінка-> розділ-> таблиця). Блоки також можуть бути видані двигуном бази даних під час ініціювання з'єднання, резервного копіювання, відновлення, процедури / тригера / функції / тощо, перекомпіляції, запуску, відключення тощо.

Я не впевнений, чи відповідає це на ваше запитання, але я сподіваюся, що це має сенс.


Дякую за Ваш коментар Ви, безумовно, найближчі поки що. Я все ще намагаюся зрозуміти, чи завжди транзакції здійснюються з точки зору блокування, які використовуються, скажімо, явними LOCKабо SELECT FOR UPDATEоператорами, або через якийсь інший механізм.
Лаїрд Нельсон

Наскільки я знаю, BEGIN TRANSACTIONсам замок не видає. Блоки з'являться після DML в рамках транзакції.
a1ex07

Уточнення - я мав на увазі, що BEGIN TRANSACTIONсам не створює замки DML; насправді він повинен видавати деякі внутрішні блокування, оскільки він повинен виділяти ресурси, додавати запис до системної таблиці (якщо такі є), яка містить активні транзакції, тощо
a1ex07

1

Я буду використовувати жаргон SQL Server, але концепції повинні бути однаковими для інших постачальників:

Кожна команда, яку ви виконуєте, виконується всередині транзакції. Цю транзакцію можна явно відкрити за допомогою BEGIN TRAN або неявно за допомогою двигуна бази даних. Причина відкритої неявної транзакції полягає в тому, що двигуну все ще потрібно підтримувати відповідність ACID та можливість відката.

Коли ви вибираєте ОНОВЛЕННЯ ДЛЯ ОНОВЛЕННЯ, це просто означає, що поки транзакція проводиться, вона матиме певний блокування.


Дякую за Ваш коментар Стільки я знаю. Але моє запитання все ще залишається: коли ця транзакція відкрита, чи здійснюється її ізоляція, тримаючи власні замки? Якщо так, то ці замки мають ті самі види замків, які я явно можу придбати? Або транзакція досягає ізоляції іншими способами?
Лаїрд Нельсон

2
Так, це той самий механізм. Ізоляція досягається за допомогою замків в обох режимах, тих же замків, які ви можете явно придбати. Різниця полягає в тому, що якщо ви явно не відкриєте транзакцію, блокування буде випущено, коли команда буде завершена, тоді як у явній транзакції блоки зберігаються, поки ви не скористаєтеся (не на 100% точні через рівень ізоляції, але це загальна ідея).
Матан Юнгман

Дякую за Ваш коментар Причиною, з якою я задаю своє запитання, є те, що я десь прочитав, що деякі бази даних використовують MVCC як засіб для здійснення транзакцій ACID, що, як мені здається, є безблочним способом зробити це. Тоді в таких випадках мені не зрозуміло, коли я колись хотів би явно видати замок. Але це, мабуть, окреме питання. :-)
Лаїрд Нельсон

@LairdNelson - це рівень ізоляції знімків для SQL Server. Існуючий, але не за замовчуванням механізм одночасності. Це за замовчуванням для Oracle або Postgresql, IIRC.
Мар’ян

0

Блокування необхідне, і вони роблять базу даних. Це запобігає пошкодженню чи визнанню недійсності даних, коли багато користувачів намагаються читати, а інші пишуть у базу даних. Транзакційна ізоляція, як правило, реалізується шляхом блокування того, до чого отримують доступ у транзакції. Погані дизайнерські програми широко використовують концепцію блокування бази даних :) !! Таким чином, щоб уникнути концентрації блокування на вашому FK та макеті даних.

Вся справа в кислоті: - прочитайте це, і це очистить ваш розум! ACID - це набір властивостей, які ви хочете застосувати під час зміни бази даних.

  • ** Атомність
  • Послідовність
  • Ізоляція
  • Міцність **

Транзакція - це сукупність пов'язаних змін, яка використовується для досягнення деяких властивостей ACID. Транзакції - це інструменти для досягнення властивостей кислоти.

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

Послідовність означає, що ви гарантуєте, що ваші дані будуть відповідні; жодне з обмежень, пов’язаних із суміжними даними, не буде порушено.

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

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

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


Дякуємо за ваш коментар Мені, принаймні, приємно відомо про властивості кислоти. Чого мені досі не зрозуміло: чи транзакції реалізують ACID, використовуючи ті самі типи замків, які я можу використовувати безпосередньо за допомогою явних LOCKзаяв, чи це роблять за допомогою іншого механізму?
Лаїрд Нельсон

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