Транзакции.

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

В ASB такими действиями в транзакции можно считать

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

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

Работу с уровнем транзакций схематично можно представить так:

  1. Начать K-й уровень некой транзакции T.

  2. Выполнить различные действия, ассоциированные с K-м уровнем транзакции T, возможно некоторые из них выполнить на K+1-м уровне транзакции T.

  3. Окончить работу с K-м уровнем транзакции T, текущим становится K-1-й уровень. Возможны два варианта: Окончание первого уровня транзакции является окончанием транзакции.

Работу с использованием транзакций схематично можно представить так:

Создать транзакцию T.

Начать 1-й уровень транзакции T.

Выполнить некоторые действия, ассоциированные с уровнем 1 транзакции T.

Начать 2-й уровень транзакции T.

Выполнить некоторые действия, ассоциированные с уровнем 2 транзакции T.

...

Выполнить некоторые действия, ассоциированные с уровнем 2 транзакции T.

Окончить 2-й уровень транзакции T.

Выполнить некоторые действия, ассоциированные с уровнем 1 транзакции T.

Окончить 1-й уровень транзакции T - это и есть окончание транзакции.

Уничтожить транзакцию T.

Возможны два варианта окончания работы с транзакцией.

Каждое подключение может вести одновременно несколько транзакций. Несвязанные между собой транзакции, выполняющиеся на одной станции, будем называть параллельными. Пример параллельных транзакций - это редактирование записей двух несвязанных между собой файлов базы данных. Параллельные транзакции не могут одновременно модифицировать одни и те же данные. Этому мешает принцип взаимодействия блокировок параллельных транзакций, а блокировками автоматически сопровождается любая операция модификации. Точно также, как и параллельные, ведут себя транзакции, выполняющиеся на разных станциях сети, поэтому и те и другие вместе будем называть единым термином независимые транзакции. Друг про друга независимые транзакции ничего не знают. Они могут только почувствовать, что некая другая транзакция мешает им поставить блокировку некоторой записи или файла или выполнить операцию модификации.

Совсем иначе в этом отношении ведет себя подчиненная транзакция. Это полноценная транзакция, обладающая всеми описанными выше свойствами. Она тоже позволяет завести несколько вложенных уровней; ставит собственные блокировки и снимает их при завершении работы; может окончиться либо фиксацией всех выполненных модификаций данных, либо откатом. Но она имеет рад особенностей:

  1. Подчиненная транзакция наследует от главной режим доступа к данным всей транзакции и всех ее таблиц БД, а также привилегию прав доступа (см. GRANT_ALL_RIGHTS), базовый срез
  2. Особое взаимодействия блокировок главной и подчиненной транзакций. Кратко можно охарактеризовать так: подчиненная транзакция имеет полный доступ к записям, разделяемо заблокированным в главной транзакции, но не имеет никакого доступа к записям, монопольно заблокированным в главной транзакции. Иначе могла бы возникнуть ситуация, что воспользовавшись этими данными подчиненная транзакция завершится фиксацией, а затем главная откатится, и результат работы подчиненной окажется неверным, т.к. она работала с "несуществующими" экземплярами данных.
  3. На старте подчиненной транзакции позиции языковых курсоров не меняются. Но если в главной транзакции позиция курсора заблокирована монопольно или конкурентно, то при входе в подчиненную курсор теряет позицию. Причина в недоступности позиций, монопольно заблокированных главной транзакцией.
  4. Позиции курсоров при окончании подчиненной транзакции определяется параметром RESTORE_CURSORS TRY-блока.
  5. Некоторые процедуры требуют предварительной блокировки, например, SAVE, REPLACE. Подчиненная транзакция использует  разделяемые блокировки главной транзакцией, как свои собственные, т.е. наследует их.

 Дополнительно о взаимодействии главной - подчиненной - независимой транзакций с учетом версионности см. здесь.

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

  1. Для следующих событий при интерактивной работе в видео-окнеесли текущее окно является зависимым, то работа выполняется на транзакции зоны, порождающей транзакцию для данного окна, а если порождающая транзакцию зона отсутствует, то эта работа выполняется на собственной параллельной транзакции. Если текущее окно является независимым, то работа выполняется на собственной параллельной транзакции.
  2. Создается новая параллельная транзакция и начинается ее первый уровень
  3. На вложенном уровне транзакции работают
  4. В ASL при выполнении TRY с атрибутом TRANSACTION создается подчиненная транзакция по отношению к транзакции вызывающей программы.

Принципы версионного подхода к ведению транзакций

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

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

С точки зрения конкретной транзакции можно выделить несколько различных типов срезов (в порядке от более древних к более свежим):

  1. Устаревшие срезы. Некоторые из них могут еще существовать в памяти сервера, но большинство уже всеми забыто. Данными этих срезов транзакция не пользуется никогда
  2. Базовый срез. Это самый свежий завершенный срез, существовавший на момент начала данной транзакции. Понятно, что для каждой транзакции базовый срез индивидуален. Но в начале своей работы несколько транзакций могут получить в качестве базового один и тот же срез.
  3. В процессе работы транзакция может модифицировать данные, формируя новый, пока еще незавершенный, срез. Такой срез будем называть собственным срезом транзакции. Условно можно считать, что в момент старта транзакция получает собственный срез, как копию базового среза, после чего она может собственный срез модифицировать.
  4. Когда транзакция завершается, ее собственный срез приобретает статус "завершенный" и может стать базовым для новых транзакций. С точки зрения незавершенных на этот момент транзакций такой срез будем называть "более свежим завершенным срезом" или для краткости просто завершенным, т.к. устаревшие (очевидно тоже завершенные) срезы транзакциями вообще никогда не рассматриваются и можно считать, что и не существуют.
  5. Самый свежий завершенный срез в конкретный момент времени будем называть последним завершенным срезом или для краткости просто последним. Очевидно, что именно последний срез для стартующей транзакции становится базовым.
  6. Жесткий срез - набор самых свежих версий всех записей всех файлов БД в конкретный момент времени, причем не важно, принадлежат эти версии завершенным или незавершенным транзакциям. Т.к. любую запись может модифицировать только одна незавершенная транзакция, то жесткий срез - это вполне конкретное понятие. Но в отличии от всех предыдущих этот срез нестабилен и меняется с течением времени.

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


См. примеры, демонстрирующие новое поведение версии 12.64.1