Меню Закрыть

Транзакция это в информатике

Содержание

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

Различают последовательные (обычные), параллельные и распределённые транзакции. Распределённые транзакции подразумевают использование более чем одной транзакционной системы и требуют намного более сложной логики (например, two-phase commit — двухфазный протокол фиксации транзакции). Также в некоторых системах реализованы автономные транзакции, или под-транзакции, которые являются автономной частью родительской транзакции.

Содержание

Пример транзакции [ править | править код ]

Пример: необходимо перевести с банковского счёта номер 5 на счёт номер 7 сумму в 10 денежных единиц. Этого можно достичь, к примеру, приведённой последовательностью действий:

  1. Прочесть баланс на счету номер 5.
  2. Уменьшить баланс на 10 денежных единиц.
  3. Сохранить новый баланс счёта номер 5.
  4. Прочесть баланс на счету номер 7.
  5. Увеличить баланс на 10 денежных единиц.
  6. Сохранить новый баланс счёта номер 7.

Эти действия представляют собой логическую единицу работы «перевод суммы между счетами», и таким образом, являются транзакцией. Если прервать данную транзакцию, к примеру, в середине, и не аннулировать все изменения, легко оставить владельца счёта номер 5 без 10 единиц, тогда как владелец счета номер 7 их не получит.

Свойства транзакций [ править | править код ]

Одним из наиболее распространённых наборов требований к транзакциям и транзакционным системам является набор AC >[1] . Вместе с тем существуют специализированные системы с ослабленными транзакционными свойствами [2] .

Уровни изоляции транзакций [ править | править код ]

В идеале транзакции разных пользователей должны выполняться так, чтобы создавалась иллюзия, что пользователь текущей транзакции — единственный. Однако в реальности, по соображениям производительности и для выполнения некоторых специальных задач, СУБД предоставляют различные уровни изоляции транзакций.

Уровни описаны в порядке увеличения изолированности транзакций и, соответственно, надёжности работы с данными.

  • 0 — Чтение неподтверждённых данных (грязное чтение) (Read Uncommitted, Dirty Read) — чтение незафиксированных изменений как своей транзакции, так и параллельных транзакций. Нет гарантии, что данные, изменённые другими транзакциями, не будут в любой момент изменены в результате их отката, поэтому такое чтение является потенциальным источником ошибок. Невозможны потерянные изменения (lost changes), возможны грязное чтение, неповторяемое чтение и фантомы.
  • 1 — Чтение подтверждённых данных (Read Committed) — чтение всех изменений своей транзакции и зафиксированных изменений параллельных транзакций. Потерянные изменения и грязное чтение не допускается, возможны неповторяемое чтение и фантомы.
  • 2 — Повторяемое чтение (Repeatable Read, Snapshot) — чтение всех изменений своей транзакции, любые изменения, внесённые параллельными транзакциями после начала своей, недоступны. Потерянные изменения, грязное и неповторяемое чтение невозможны, возможны фантомы.
  • 3 — Сериализуемый (Serializable) — сериализуемые транзакции. Результат параллельного выполнения сериализуемой транзакции с другими транзакциями должен быть логически эквивалентен результату их какого-либо последовательного выполнения. Проблемы синхронизации не возникают.

Чем выше уровень изоляции, тем больше требуется ресурсов, чтобы его обеспечить. Соответственно, повышение изолированности может приводить к снижению скорости выполнения параллельных транзакций, что является «платой» за повышение надёжности.

В СУБД уровень изоляции транзакций можно выбрать как для всех транзакций сразу, так и для одной конкретной транзакции. По умолчанию в большинстве баз данных используется уровень 1 (Read Committed). Уровень 0 используется в основном для отслеживания изменений длительных транзакций или для чтения редко изменяемых данных. Уровни 2 и 3 используются при повышенных требованиях к изолированности транзакций.

Реализация [ править | править код ]

Полноценная реализация уровней изоляции и свойств ACID представляет собой нетривиальную задачу. Обработка поступающих данных приводит к большому количеству маленьких изменений, включая обновление как самих таблиц, так и индексов. Эти изменения потенциально могут потерпеть неудачу: закончилось место на диске, операция занимает слишком много времени (timeout) и т. д. Система должна в случае неудачи корректно вернуть базу данных в состояние до транзакции.

Первые коммерческие СУБД (к примеру, IBM DB2), пользовались исключительно блокировкой доступа к данным для обеспечения свойств ACID. Но большое количество блокировок приводит к существенному уменьшению производительности. Есть два популярных семейства решений этой проблемы, которые снижают количество блокировок:

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

При упреждающей журнализации, используемой в Sybase и MS SQL Server до версии 2005, все изменения записываются в журнал, и только после успешного завершения — в базу данных. Это позволяет СУБД вернуться в рабочее состояние после неожиданного падения системы. Теневые страницы содержат копии тех страниц базы данных на начало транзакции, в которых происходят изменения. Эти копии активизируются после успешного завершения. Хотя теневые страницы легче реализуются, упреждающая журнализация более эффективна [4] .

Читайте также:  Legacy pci device что это

Дальнейшее развитие технологий управления базами данных привело к появлению безблокировочных технологий. Идея контроля над параллельным доступом с помощью временных меток (timestamp-based concurrency control) была развита и привела к появлению многоверсионной архитектуры MVCC. Эти технологии не нуждаются ни в журнализации изменений, ни в теневых страницах. Архитектура, реализованная в Oracle 7.х и выше, записывает старые версии страниц в специальный сегмент отката, но они все ещё доступны для чтения. Если транзакция при чтении попадает на страницу, временная метка которой новее начала чтения, данные берутся из сегмента отката (то есть используется «старая» версия). Для поддержки такой работы ведётся журнал транзакций, но в отличие от «упреждающей журнализации», он не содержит данных. Работа с ним состоит из трёх логических шагов:

  1. Записать намерение произвести некоторые операции
  2. Выполнить задание, копируя оригиналы изменяемых страниц в сегмент отката
  3. Записать, что всё сделано без ошибок

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

  • Если повреждена запись, то сбой произошёл во время проставления отметки в журнале. Значит, ничего важного не потерялось, игнорируем эту ошибку.
  • Если все записи помечены как успешно выполненные, то сбой произошёл между транзакциями, здесь также нет потерь.
  • Если в журнале есть незавершённая транзакция, то сбой произошёл во время записи на диск. В этом случае мы восстанавливаем старую версию данных из сегмента отката.

Firebird вообще не имеет ни журнала изменений, ни сегмента отката, а реализует MVCC, записывая новые версии строк таблиц прямо в активное пространство данных. Так же поступает MS SQL 2005. Теоретически это даёт максимальную эффективность при параллельной работе с данными, но ценой является необходимость «сборки мусора», то есть удаления старых и уже не нужных версий данных.

Управление транзакциями.

Все современные промышленные СУБД и часть настольных поддерживают работу с транзакциями. Механизм транзакций важен во многих отношениях. Мы в настоящем курсе рассмотрим его с двух точек зрения – как основу для восстановления целостности баз данных и как часть механизма управления одновременной работой с данными нескольких пользователей. Но для того, чтобы понять роль транзакций необходимо рассмотреть транзакции как таковые. В первую очередь, дадим определение понятия «транзакция».

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

То есть, транзакция, вне зависимости от количества входящих в нее операций, рассматривается как единое целое, и может либо целиком завершиться успешно, либо не выполниться вообще, в случае, если в какой-либо из операций произойдет сбой. При успешном завершении транзакция фиксируется, выполняется операция «commit». При возникновении сбоя уже выполненные действия отменяются и транзакция «откатывается», выполняется операция «rollback».

Наиболее популярным примером транзакции, который помогает лучше понять ее суть и необходимость, является операция перечисления денежных средств между банковскими счетами.

Приведем одну из возможных последовательностей действий, нужных для выполнения этой операции:

1. Проверить доступность счета, с которого предполагается списать деньги, и достаточность средств на нём. Это операция чтения данных, возможно, из нескольких таблиц).

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

3. Уменьшить значение остатка на счете-источнике. Это операция модификации данных.

4. Увеличить значение остатка на счете-получателе. Это операция модификации данных.

5. Создать запись о проведенной операции в журнале операций. Это операция создания новой записи.

Можно предложить и другие варианты выполнения этой операции, но главным является то, что вся эта последовательность либо должна выполняться, либо ни одна из операций не должна быть выполнена. Очевидно, что если мы остановимся, скажем, на шаге 4, то средства со счета-источника просто исчезнут – будут списаны «в никуда». То есть, согласованность данных будет нарушена. Кроме того, необходимо гарантировать, что в процессе выполнения транзакции с задействованными в ней счетами не будут выполняться никакие другие операции. В самом деле, если после того, как мы проверили достаточность средств на счете-источнике, эти средства будут с него списаны другой операцией – мы опять-таки скорее всего столкнемся с нарушениями согласованности данных.

Читайте также:  C vector удаление элемента

Разумеется, поддержка механизма транзакций технически может быть и очень сложной – при наличии десятков и сотен пользователей и тысяч обращений к данным обеспечить независимость этих обращений друг от друга, а также возможность отмены операций и возврата базы данных к исходному состоянию непросто. Для реализации этого механизма могут задействоваться различные средства, но есть свойства, которыми должны обладать транзакции и поддерживающая их система. Обычно для обозначения этих свойств используют аббревиатуру ACID – Atomicity, Consistency, Isolation, Durability. В переводе на русский – Атомарность, Согласованность, Изолированность и Долговечность. Рассмотрим эти свойства подробнее.

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

Согласованность – достаточно сложное понятие, которое несколько шире понятия целостности данных. Если целостность данных – это выполнение всех имеющихся в БД ограничений целостности (внутризаписных, межзаписных, ограничений внешних ключей и так далее), то согласованность означает еще и соответствие базы данных бизнес-правилам. В частности, из ограничений целостности может следовать запрет на отрицательное значение остатка на счете (то есть, соответствующего атрибута), но, скажем, требования равенства списываемой и зачисляемой суммы при переводе средств со счета на счет – это уже бизнес-правило, которое при помощи ограничений целостности не выразить.

Как уже было сказано, предполагается, что транзакция переводит БД из одного согласованного состояния в другое, но обеспечить это должны программисты, задающие последовательность операций. Роль СУБД здесь – гарантировать, что все операции будут выполнены успешно (или не будут выполнены вообще). Кроме того, в процессе выполнения транзации БД может проходить через ряд несогласованных состояний (скажем, в приведенном выше примере с переводом средств система несогласованна после выполнения операции 3 до выполнения операции 4).

Изолированность – это свойство транзакции выполняться независимо друг от друга. То есть, в процессе выполнения одной транзакции другие не могут повлиять на результат ее выполнения. Обеспечение совершенной независимости транзакций друг от друга требует и соответствующих ресурсов, и отрицательно сказывается на скорости выполнения операций с данными, так что существует несколько, так называемых, уровней изолированности, которые будут рассмотрены далее.

Долговечность – это свойство транзакции сохраняться в системе «навсегда» после успешного завершения. Очевидно, что в процессе работы СУБД могут возникать сбои оборудования, отключения питания, иные ошибки, но гарантируется, что если выдано сообщение об успешном завершении транзакции, то изменения, внесенные ей в данные, сохранятся в любом случае и когда состояние базы данных будет восстановлено после сбоя, эти изменения никуда не денутся. Разумеется, речь не идет о случаях, когда полностью вышел из строя носитель информации, на котором находилась база данных, и ее пришлось восстанавливать из резервной копии. Хотя даже и в этих случаях, как будет обсуждаться далее, выполненные транзакции иногда могут быть восстановлены.

Теперь, после рассмотрения понятия транзакции и ее основных свойств, мы можем перейти к обсуждению вопросов использования транзакций для реализации восстановления базы данных после сбоев и для организации параллельной работы нескольких пользователей.

Не нашли то, что искали? Воспользуйтесь поиском:

Пример: необходимо перевести с банковского счёта номер 5 на счёт номер 7 сумму в 10 денежных единиц. Этого можно достичь, к примеру, приведённой последовательностью действий:

  • Начать транзакцию

прочесть баланс на счету номер 5 уменьшить баланс на 10 денежных единиц сохранить новый баланс счёта номер 5 прочесть баланс на счету номер 7 увеличить баланс на 10 денежных единиц сохранить новый баланс счёта номер 7

  • Окончить транзакцию

Эти действия представляют собой логическую единицу работы «перевод суммы между счетами», и таким образом, являются транзакцией. Если прервать данную транзакцию, к примеру, в середине, и не аннулировать все изменения, легко оставить владельца счёта номер 5 без 10 единиц, тогда как владелец счета номер 7 их не получит.

Свойства транзакций

Одним из наиболее распространённых наборов требований к транзакциям и транзакционным системам является набор AC >[1] .

Уровни изоляции транзакций

В идеале транзакции разных пользователей должны выполняться так, чтобы создавалась иллюзия, что пользователь текущей транзакции — единственный. Однако в реальности, по соображениям производительности и для выполнения некоторых специальных задач, СУБД предоставляют различные уровни изоляции транзакций. Уровни описаны в порядке увеличения изоляции транзакций и надёжности работы с данными

  • 0 — Неподтверждённое чтение (Read Uncommitted, Dirty Read, грязное чтение) — чтение незафиксированных изменений своей транзакции и параллельных транзакций, возможны нечистые, неповторяемые чтения и фантомы
  • 1 — Подтверждённое чтение (Read Committed) — чтение всех изменений своей транзакции и зафиксированных изменений параллельных транзакций, нечистые чтения невозможны, возможны неповторяемые чтения и фантомы;
  • 2 — Повторяемое чтение (Repeatable Read, Snapshot) — чтение всех изменений своей транзакции, любые изменения, внесённые параллельными транзакциями после начала своей, недоступны, нечистые и неповторяемые чтения невозможны, возможны фантомы;
  • 3 — Упорядоченный — (Serializable, сериализуемый) — упорядоченные (сериализуемые) транзакции. Идентичен ситуации, при которой транзакции выполняются строго последовательно, одна после другой, то есть результат действия которых не зависит от порядка выполнения шагов транзакции (запрещено чтение всех данных, изменённых с начала транзакции, в том числе и своей транзакцией). Фантомы невозможны.
Читайте также:  Что означает смайлик красное сердечко в ватсапе

Чем выше уровень изоляции, тем больше требуется ресурсов, чтобы их поддерживать.

В СУБД уровень изоляции транзакций можно выбрать как для всех транзакций сразу, так и для одной конкретной транзакции. По умолчанию в большинстве баз данных используется уровень 1 (Read Committed). Уровень 0 используется в основном для отслеживания изменений длительных транзакций или для чтения редко изменяемых данных. Уровни 2 и 3 используются при повышенных требованиях к изолированности транзакций.

Реализация

Полноценная реализация уровней изоляции и свойств ACID представляет собой нетривиальную задачу. Обработка поступающих данных приводит к большому количеству маленьких изменений, включая обновление как самих таблиц, так и индексов. Эти изменения потенциально могут потерпеть неудачу: закончилось место на диске, операция занимает слишком много времени (timeout) и т. д. Система должна в случае неудачи корректно вернуть базу данных в состояние до транзакции.

Первые коммерческие СУБД (к примеру, IBM DB2), пользовались исключительно блокировкой доступа к данным для обеспечения свойств ACID. Но большое количество блокировок приводит к существенному уменьшению производительности. Есть два популярных семейства решений этой проблемы, которые снижают количество блокировок:

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

При упреждающей журнализации, используемой в Sybase и MS SQL Server до версии 2005, все изменения записываются в журнал, и только после успешного завершения — в базу данных. Это позволяет СУБД вернуться в рабочее состояние после неожиданного падения системы. Теневые страницы содержат копии тех страниц базы данных на начало транзакции, в которых происходят изменения. Эти копии активизируются после успешного завершения. Хотя теневые страницы легче реализуются, упреждающая журнализация более эффективна [3]

Дальнейшее развитие технологий управления базами данных привело к появлению безблокировочных технологий. Идея контроля за параллельным доступом с помощью временных меток (timestamp-based concurrency control) была развита и привела к появлению многоверсионной архитектуры MVCC. Эти технологии не нуждаются ни в журнализации изменений, ни в теневых страницах. Архитектура, реализованная в Oracle 7.х и выше, записывает старые версии страниц в специальный сегмент отката, но они все ещё доступны для чтения. Если транзакция при чтении попадает на страницу, временная метка которой новее начала чтения, данные берутся из сегмента отката (то есть используется «старая» версия). Для поддержки такой работы ведётся журнал транзакций, но в отличие от «упреждающей журнализации», он не содержит данных. Работа с ним состоит из трёх логических шагов:

  1. Записать намерение произвести некоторые операции
  2. Выполнить задание, копируя оригиналы изменяемых страниц в сегмент отката
  3. Записать, что всё сделано без ошибок

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

  • Если повреждена запись, то сбой произошёл во время проставления отметки в журнале. Значит, ничего важного не потерялось, игнорируем эту ошибку.
  • Если все записи помечены как успешно выполненные, то сбой произошёл между транзакциями, здесь также нет потерь.
  • Если в журнале есть незавершённая транзакция, то сбой произошёл во время записи на диск. В этом случае мы восстанавливаем старую версию данных из сегмента отката.

Firebird вообще не имеет ни журнала изменений, ни сегмента отката, а реализует MVCC, записывая новые версии строк таблиц прямо в активное пространство данных. Так же поступает MS SQL 2005. Теоретически это даёт максимальную эффективность при параллельной работе с данными, но ценой является необходимость «сборки мусора», то есть удаления старых и уже не нужных версий данных.

Рекомендуем к прочтению

Добавить комментарий

Ваш адрес email не будет опубликован.