Почему незавершенные транзакции должны отменяться в обратном порядке?


19

У меня есть журнал базы данных, где некоторые транзакции выигрывают (они фиксируются до сбоя), а некоторые проигрывают (еще не зафиксированы). В классе мы узнали, что действия проигравших должны быть отменены задом наперед.

Есть ли причина делать это задом наперед? Может ли кто-нибудь привести простой пример журнала, в котором прямая отмена дала бы неправильные результаты?


Не стоит ли задавать этот вопрос на другом, более конкретном сайте?
nbro

Ответы:


35

Оригинальные транзакции:

  1. Вставить запись .r
  2. Обновите некоторое поле из r .fr

Вперед отменить:

  1. Удалить запись .r
  2. Отмените обновление на - о, подождите, r больше не существует! Это вызывает ошибку.rr

Должны ли вещи быть физически индивидуально отменены в обратном порядке, если система может выяснить, к какому состоянию нужно вернуться, и может применить все необходимые изменения перед обработкой чего-либо еще?
суперкат

11
Отмена изменений в обратном порядке делает это легко. Почему вы пытаетесь сделать это тяжело для себя?
gnasher729

1
Нет, система не будет делать все, но все равно поймет это в обратном порядке.
Зло

3
Во многих реальных системах баз данных сделать это не в обратном порядке невозможно даже из-за ключевых ограничений таблиц.
SeanR

11

Чтобы добавить к ответу DylanSp, попытка обновить поле в несуществующей записи не удастся, но результатом все равно будет ожидаемый результат: запись r не существует.

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

  1. Вставить заказ O.
  2. Вставить строку заказа L.

Предположим, что нереально, что каждая OrderLine должна быть связана с Order.

Теперь откат транзакции, начиная с удаления ордера, не удастся, потому что это нарушит наше бизнес-правило.

Так после

  1. Удалить заказ O. (FAIL)
  2. Удалить Ordeline L. (УСПЕХ)

Мы можем получить существующий Заказ (без Линии Заказа).

Конечно, в этом случае мы могли бы использовать каскадное удаление, но это означало бы, что шаг 2 завершится неудачей (без последствий). Хуже того, это может быть нежелательным для реализации каскадного удаления заказов.


Хорошо, это имеет смысл. Thx для вашей помощи
prjctdth

Уместно ли предположить, что ограничения не были нарушены ни до, ни после транзакции при «нормальных» обстоятельствах? Под нормальным я подразумеваю, что транзакция не провалилась бы, если бы только один человек использовал базу данных. Если это правда, почему важно не вводить нарушения ограничений в процессе отмены? Кажется, что ограничения могут быть отключены в начале отмены и включены после завершения операции.
Noctis Skytower

2
@NoctisSkytower Отключение ограничений во время обычной операции ввода-вывода делает их бесполезными. Они существуют по причине. Мой пример ясно иллюстрирует, как ограничения могут быть выполнены при нормальных обстоятельствах, но нарушены во время отката. Отключение ограничений во время отката излишне усложняет ситуацию и решает неправильную проблему. Проблема не в ограничении, а в нарушении его из-за неправильной попытки отката.
oerkelens

Да, это имеет смысл, но зачем проверять ограничения во время отката? Если предположить, что откаты гарантированно завершены без проблем, зачем излишне тратить время на проверку ограничений, если известно, что они не будут нарушены к моменту завершения отката? Кстати, это должно быть гарантией, потому что, если откат не удался, БД, по-видимому, должен был бы выполнить откат, чего он не может сделать.
Noctis Skytower

1
@NoctisSkytower должно быть невозможно, чтобы БД находилась в состоянии, когда ограничения нарушены, даже если это временное состояние. Если весь откат является атомарным, то не имеет значения, в каком порядке он происходит, потому что нет порядка, это одна инструкция, которая «происходит все сразу». если есть две или более транзакции, которые откатываются отдельно в некотором порядке, то обязательно, чтобы порядок был таким, чтобы любой наблюдатель, считывающий данные посередине, мог видеть только ситуацию, когда все ограничения выполняются.
Петерис

6

Пойдем по аналогии: скажем, вы идете на ужин.

  1. Надень носки.
  2. Надень обувь.
  3. Встаньте.
  4. Идите к двери.

Тогда вам позвонят. Ужин планы отменены.

  1. Сними носки.
  2. Сними обувь
  3. Сядьте.
  4. Уходи от двери.

Там что-то идет не так. Вы можете споткнуться и пораниться. Или, более вероятно, вы поймете, что некоторые действия нельзя отменить, пока последующие действия не будут отменены первыми.

Отмена последнего действия, которое вы делали, возвращает вас туда, где вы были, когда произошел следующий шаг. Затем вы отменяете этот шаг и повторяете, двигаясь назад, пока ничего не останется. С другой стороны, отмена первого шага может быть невозможна, учитывая состояния, следующие за последующими шагами.

говоря математически: действия могут не переключаться, поэтому всякий раз, когда имеет значение, какой шаг вы делаете первым или вторым, будет иметь значение порядок, в котором вы отменяете шаги.


3

Это правильно, потому что транзакции строятся друг на друге, и результат транзакции очень сильно зависит от ситуации до ее совершения.

Давайте посмотрим на финансовые транзакции:

(в начале, до того, как сделка aдолжна мне 100 долларов США)

  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.

Почему ОБА совершенные и незафиксированные транзакции записываются в файл журнала повторов? Причина этого заключается в обеспечении восстановления на определенный момент времени.

Это означает, что содержимое файла «redo log» НЕ соответствует транзакциям. По этой причине всякий раз, когда журнал повторов используется для применения подтвержденных транзакций к файлам данных, «Журнал отмен» ДОЛЖЕН также использоваться для отката незафиксированных транзакций.

Почему транзакции в «журнале отмены» откатываются в обратном порядке? Транзакция 300 добавила 50 к существующему значению каждого столбца каждой строки. Следовательно, если транзакция 200 откатывается первой, значения изменятся с 251, 252 и 253 на 201, 202 и 203. Если транзакция 300 затем откатится последней, значения будут 151, 152 и 153 - которые не совпадают. исходные совершенные ценности.

ССЫЛКИ:

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


0

Это по сути не правда. Откат может просто повторно применить блоки, которые были кэшированы в журнале отмены, так что конечное состояние совпадает с начальным состоянием. Поскольку журнал был записан в порядке пересылки, мой откат также был применен в порядке пересылки. Порядок не имеет значения, потому что откат будет повторяться до тех пор, пока файл журнала не будет помечен как исчерпанный.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.