Транзакции
В системе с преимущественной многозадачностью ноток может быть прерван в любой момент. Обычно перед выполнением очередной машинной команды система смотрит, есть ли прерывание. Если есть и приоритет его достаточно высок, то текущая команда не выполняется, а система переходит в режим обработки прерывания. Если программа написана без учета этого обстоятельства (not thread-safe), то последствия могут быть неожиданными. Например, если поток проверяет значение какого-то глобального флага и в зависимости от его значения выполняет разветвление, то возможна ошибка из-за того, что флаг мог быть изменен другим потоком, перехватившим управление в промежутке между этими двумя командами. Для создания thread-safe программист должен уметь синхронизировать доступ к критическим объектам так, чтобы один поток не портил работу другого.
Важным понятием, которое имеет отношение к рассматриваемой проблеме и используется при описании алгоритмов управления источниками данных, является транзакция. Представьте, что один клиент банка производит депозит чека, который получен им от другого клиента. При выполнении этой операции нормально функционирующая система должна либо изменить оба счета, либо оставить все без изменений. Если на счету клиента, выписавшего чек, есть указанная сумма, то этот счет уменьшается, а счет второго клиента увеличивается. Если указанной суммы на счету первого клиента не оказалось, то оба счета должны остаться без изменений. Идея транзакции заключается в том, что после проведения изменений в записях базы данных все они либо принимаются (committed), либо отвергаются (rolled-back или aborted).
Транзакция – это множество операций, которые выполняются либо все, либо ни одна. Транзакция представляет собой последовательность операций над БД (базой данных), рассматриваемых СУБД как единое целое и необходимых для поддержания ее логической целостности. То свойство, что каждая транзакция начинается при целостном состоянии БД и оставляет это состояние целостным после своего завершения, делает очень удобным использование этого понятия как единицы активности пользователя по отношению к БД. Для поддержки многозадачности требуются следующие механизмы обработки данных:
- начало транзакции, › изменение данных, › принятие изменений (commit);
- начало транзакции, › изменение данных, › отмена транзакции (roll back);
- восстановление системы после программного или аппаратного сбоя;
- восстановление системы после потери данных на диске;
- архивирование базы данных;
- создание контрольных точек (checkpoints) – копий текущих состояний для возможности их восстановления.
Одним из основных требований к СУБД является надежность хранения данных во внешней памяти. Под надежностью хранения понимается то, что СУБД должна быть в состоянии восстановить последнее согласованное состояние БД после любого аппаратного или программного сбоя. Обычно рассматриваются два возможных вида аппаратных сбоев: так называемые мягкие сбои, которые можно трактовать как внезапную остановку работы компьютера, например аварийное выключение питания, и жесткие сбои, характеризуемые потерей информации на носителях внешней памяти. Примерами программных сбоев могут быть:
- аварийное завершение работы СУБД по причине ошибки в программе или в результате некоторого аппаратного сбоя,
- аварийное завершение пользовательской программы, в результате чего некоторая транзакция остается незавершенной.
Во всех случаях придерживаются стратегии "упреждающей" записи в журнал, так называемого протокола WAL – Write Ahead Log. Она заключается в том, что запись об изменении любого объекта БД должна попасть во внешнюю память журнала раньше, чем измененный объект попадет во внешнюю память основной части БД. Известно, что если в СУБД корректно соблюдается протокол WAL, то с помощью журнала можно решить все проблемы восстановления БД после любого сбоя.