292
правки
Изменения
Новая страница: «== Зачем == Пусть у нас есть несколько узлов (процессов), которых хранят какие-то ''непересе…»
== Зачем ==
Пусть у нас есть несколько узлов (процессов), которых хранят какие-то ''непересекающиеся'' данные.
Например, на одном узле хранятся банковские счета пользователей на "А", на другом — на "Б", и так далее.
Тогда мы можем хотеть транзакционно изменять данные на разных узлах (см. <code>BEGIN TRANSACTION</code> и <code>COMMIT TRANSACTION</code> в SQL).
{{Определение
|definition=
'''Транзакция''' — это единица работы над множеством элементов из базы данных, которую можно в процессе работы целиком '''отменить''' (либо сама база данных, либо пользователь, см. <code>ROLLBACK TRANSACTION</code>), либо '''подтвердить''' (база данных может иногда не справиться, тогда транзакция отменяется).
}}
У транзакции обычно выделяют свойства по аббревиатуре ACID:
# '''A'''tomicity (атомарность) — транзакция либо полностью '''применила''' все свои изменения, либо полностью '''откатилась''' (отменилась)
# '''C'''onsitency (согласованность) — в конце транзакции система находится в согласованном состоянии
# '''I'''solation (изолированность) — параллельные транзакции не должны влиять друг на друга (например, при помощи phantom reads), а должны выполняться как будто последовательно
# '''D'''urability (надёжность) — завершённые (commited) транзакции сохраняются даже в случае сбоев и перезапуска системы
== Атомарность и надёжность ==
Предположим, что нам нужны только атомарность и надёжность.
Самое сложное — откатывать транзакцию, если что-то пошло не так.
Есть два основных способа этого добиться.
=== Undo log ===
Каждый узел сначала записывает предыдущие значения в надёжный журнал (лог, обычно append-only и сохраняется на диск), а только потом изменяет состояние в памяти.
Когда транзакция подтверждается, надо записать произведённые изменения в надёжное место и можно стереть кусок журнала.
Если транзакцию надо откатить (например, после перезапуска системы в журнале нет записи "транзакция успешна"), то мы идём с конца журнала и восстанавливаем старые значения.
=== Redo log ===
Мы вообще не делаем изменения в данных до подтверждения транзакции, а просто пишем в журнал все операции, которые надо произвести с данными.
Когда транзакция успешно завершается, у нас две опции:
* Изменить данные прямо на диске.
* Записать об этом в журнал на диск (append-only), а состояние просто каждый раз восстанавливать из этого журнала. Иногда делать checkpoint'ы для сохранения состояния. Это сейчас на практике популярнее.
== Согласованность и изоляция ==
Пусть у нас есть несколько узлов (процессов), которых хранят какие-то ''непересекающиеся'' данные.
Например, на одном узле хранятся банковские счета пользователей на "А", на другом — на "Б", и так далее.
Тогда мы можем хотеть транзакционно изменять данные на разных узлах (см. <code>BEGIN TRANSACTION</code> и <code>COMMIT TRANSACTION</code> в SQL).
{{Определение
|definition=
'''Транзакция''' — это единица работы над множеством элементов из базы данных, которую можно в процессе работы целиком '''отменить''' (либо сама база данных, либо пользователь, см. <code>ROLLBACK TRANSACTION</code>), либо '''подтвердить''' (база данных может иногда не справиться, тогда транзакция отменяется).
}}
У транзакции обычно выделяют свойства по аббревиатуре ACID:
# '''A'''tomicity (атомарность) — транзакция либо полностью '''применила''' все свои изменения, либо полностью '''откатилась''' (отменилась)
# '''C'''onsitency (согласованность) — в конце транзакции система находится в согласованном состоянии
# '''I'''solation (изолированность) — параллельные транзакции не должны влиять друг на друга (например, при помощи phantom reads), а должны выполняться как будто последовательно
# '''D'''urability (надёжность) — завершённые (commited) транзакции сохраняются даже в случае сбоев и перезапуска системы
== Атомарность и надёжность ==
Предположим, что нам нужны только атомарность и надёжность.
Самое сложное — откатывать транзакцию, если что-то пошло не так.
Есть два основных способа этого добиться.
=== Undo log ===
Каждый узел сначала записывает предыдущие значения в надёжный журнал (лог, обычно append-only и сохраняется на диск), а только потом изменяет состояние в памяти.
Когда транзакция подтверждается, надо записать произведённые изменения в надёжное место и можно стереть кусок журнала.
Если транзакцию надо откатить (например, после перезапуска системы в журнале нет записи "транзакция успешна"), то мы идём с конца журнала и восстанавливаем старые значения.
=== Redo log ===
Мы вообще не делаем изменения в данных до подтверждения транзакции, а просто пишем в журнал все операции, которые надо произвести с данными.
Когда транзакция успешно завершается, у нас две опции:
* Изменить данные прямо на диске.
* Записать об этом в журнал на диск (append-only), а состояние просто каждый раз восстанавливать из этого журнала. Иногда делать checkpoint'ы для сохранения состояния. Это сейчас на практике популярнее.
== Согласованность и изоляция ==