Чому необмежені транзакції потрібно скасувати в зворотному порядку?


19

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

Чи є якась причина для цього назад? Чи може хтось навести простий приклад журналу, коли вперед скасування дасть неправильні результати?


Чи не слід це питання задавати на іншому більш конкретному веб-сайті?
nbro

Відповіді:


35

Оригінальні транзакції:

  1. Вставити запис .r
  2. Оновіть деяке поле з .rfr

Скасувати вперед:

  1. Видалити запис .r
  2. Поверніть оновлення до - о, зачекайте, більше не існує! Це спричиняє помилку.rrr

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

11
Скасування змін у зворотному порядку дозволяє легко. Чому б ти намагався зробити це важким для себе?
gnasher729

1
Ні, система не зробить усе, але все одно буде з'ясовувати це у зворотному порядку.
Зло

3
У багатьох реальних системах баз даних це робити не в зворотному порядку було б навіть неможливо через ключові обмеження в таблицях.
SeanR

11

Якщо додати відповідь DylanSp, спроба оновити поле в неіснуючій записи не вдасться, але результат все одно буде очікуваним результатом: запис r не існує.

Однак врахуйте ситуацію, коли видалення запису фактично не вдасться:

  1. Вставити наказ О.
  2. Вставити наказ L

Припустимо, не нереально, що кожен OrderLine повинен бути пов'язаний із замовленням.

Зараз відкат транзакції, починаючи зі видалення Замовлення, не вдасться, оскільки це порушить наше ділове правило.

Так після

  1. Видалити замовлення O. (FAIL)
  2. Видалити Ordeline L. (Успіх)

Ми можемо створити замовлення (без лінії замовлення).

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


Гаразд, це має сенс. Thx для вашої допомоги
prjctdth

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

2
@NoctisSkytower Вимкнення обмежень під час звичайної операції вводу / виводу робить їх марними. Вони існують не просто так. Мій приклад чітко ілюструє, як обмеження можуть бути дотримані за звичайних обставин, але порушені під час відкату. Вимкнення обмежень під час відкоту є зайвим завданням і виправляє неправильну проблему. Проблема не в обмеженні, проблема полягає в порушенні її шляхом неправильної спроби відкотити.
oerkelens

Так, це має сенс, але навіщо перевіряти обмеження під час відкату? Якщо припустити, що зворотний відкат призначений для гарантованого завершення без проблем, навіщо зайво витрачати час на перевірку обмежень, якщо відомо, що вони не будуть порушені до моменту завершення відкату? BTW, це має бути гарантією, оскільки якщо відкат не вдався, БД, здавалося б, повинен прокататись вперед, чого він не може зробити.
Noctis Skytower

1
@NoctisSkytower, БД не може перебувати в стані, коли обмеження порушуються, навіть якщо це тимчасовий стан. Якщо весь відкат є атомним, то не має значення, в якому порядку це відбувається, оскільки немає порядку, це єдина інструкція, що "відбувається все відразу". якщо є дві або більше транзакцій, які повертаються назад окремо в певному порядку, то обов'язково, щоб наказ був таким, що будь-який спостерігач, який читає дані посередині, може побачити лише ситуацію, коли всі обмеження мають місце.
Пітерис

6

Пройдемо за аналогією: скажіть, ви виходите на вечерю.

  1. Одягніть шкарпетки.
  2. Одягніть взуття.
  3. Встаньте.
  4. Підійдіть до дверей.

Потім ви отримуєте телефонний дзвінок. Плани на вечерю скасовані.

  1. Зніміть шкарпетки.
  2. Знімайте взуття.
  3. Сідайте.
  4. Ідіть від дверей.

Щось там піде не так. Ви можете подорожувати і нашкодити собі. Або, швидше за все, ви зрозумієте, що деякі дії не можна скасувати, доки пізні дії не будуть скасовані спочатку.

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

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


3

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

Давайте розглянемо фінансові операції:

(на початку, перед тим, як транзакції aзаборгували мені 100 USD)

  1. a заборгував мені 100 доларів США (зараз загальна заборгованість 200)
  2. aотримує 10% знижку на те, що він мені зобов’язаний. (зараз загальна заборгованість 180)

Скажімо, я хочу скасувати дві транзакції.

Якщо ми скасуємо перше, ми закінчимо:

  1. нижчий борг 100 (тепер борг 80)
  2. скасуйте знижку 10% (тепер у вас борг 80 / 0,9 = 88)

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

  1. скасувати знижку - зараз борг становить 200
  2. нижчий 100 боргу - зараз борг 100

2

Припустимо, що існує таблиця T лише з одним стовпцем.

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

At 8:00 A.M., Transaction 100 inserts rows with values 101, 102 and 103 into table T. At 8:10 A.M., Transaction 100 is committed and the commit for transaction 100 completes. At 8:15 A.M., Transaction 200 updates row 101 to 201, 102 to 202 and 103 to 203. At 8:20 A.M., Transaction 200 has not been committed and remains in the undo log of the database. At 8:25 A.M., Transaction 300 increments each row by 50, changing row 201 to 251, 202 to 252, and 203 to 253. At 8:30 A.M., Transaction 300 has not been committed and remains in the undo log of the database. At 8:35 A.M., The instance providing access to the database crashes.

At 8:40 A.M., The instance is restarted, and the database files are opened as the instance is started:

              The committed values in T are still 101, 102 and 103.

              Since 201, 202, and 203, and 251, 252 and 253
              are not committed, if they are written into the "redo
              log" of the database, there is a need to "roll back"
              the transactions AFTER the "redo log" is applied.

              Since 201, 202, and 203, and 251, 252 and 253
              are not committed, they are in the "undo log"
              of the database.

              The undo log of the database is used BOTH to (1) roll
              back a transaction that is deliberately rolled 
              back in the memory structure of the database instance, 
              and also (2) during the instance recovery at 8:40 A.M.

At 8:41 A.M., The redo log has been applied, and the T table contains values 251, 252 and 253 in the instance memory.

              The undo log has not yet been applied.

At 8:42 A.M., The undo log is applied in the reverse order: Uncommitted transaction 300 is undone, and Uncommitted transaction 200 is undone.

Чому BOTH вчинені та непослані транзакції записуються у файл журналу повтору? Причиною цього є забезпечення точного відновлення.

Це означає, що вміст файлу "повторного журналу" НЕ узгоджується з транзакціями. З цієї причини, кожного разу, коли повторний журнал використовується для застосування вчинених транзакцій до файлів даних, "скасувати журнал" ОБОВ'ЯЗКОВО слід використовувати також для того, щоб повернути незавершені транзакції.

Чому транзакції з "журналу скасування" повертаються у зворотному порядку? Транзакція 300 додала 50 до існуючого значення кожного стовпця кожного рядка. Отже, якщо транзакція 200 буде повернута спочатку, значення зміняться з 251, 252 та 253 до 201, 202 та 203. Якщо транзакція 300 була згорнута останньою, значення будуть 151, 152 та 153 - які не відповідають первісні цілісні значення.

ДОВІДКИ

https://asktom.oracle.com/pls/asktom/f?p=100:11:45::::P11_QUESTION_ID:1670195800346464273


0

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

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