Написано: 05.04.2023

12. Транзакции

В этой главе дается определение транзакции и описывается, как БД обрабатывает транзакции.

Введение в транзакции

Транзакция – это логическая, атомарная единица работы, содержащая один или несколько операторов SQL.

Транзакция группирует SQL-инструкции таким образом, что либо все они фиксируются, что означает, что они применяются к БД, либо все откатываются, что означает, что они удаляются из БД. БД Oracle присваивает каждой транзакции уникальный идентификатор, называемый transaction ID.

Все транзакции Oracle соблюдают основные свойства транзакции БД, известные как свойства ACID. ACID – это аббревиатура от следующего:

  • Атомарность
    Выполняются все задачи транзакции или не выполняется ни одна из них. Частичных транзакций не существует. Например, если транзакция начинает обновлять 100 строк, но система завершается сбоем после 20 обновлений, то БД откатывает изменения в эти 20 строк.

  • Согласованность (Consistency)
    Транзакция переводит БД из одного согласованного состояния в другое. Например, в банковской транзакции, которая дебетует сберегательный счет и зачисляет средства на расчетный счет, сбой не должен приводить к тому, что БД зачисляет средства только на один счет, что привело бы к несогласованности данных.

  • Изолированность
    Эффект транзакции не виден другим транзакциям до тех пор, пока транзакция не будет зафиксирована. Например, один пользователь, обновляющий таблицу hr.employees, не видит незафиксированных изменений в employees, внесенных одновременно другим пользователем. Таким образом, пользователям кажется, что транзакции выполняются последовательно.

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

Использование транзакций является одним из наиболее важных отличий между СУБД и файловой системой.

Пример транзакции: дебет и кредит счета

Для иллюстрации концепции транзакции, рассмотрим банковскую БД.

Когда клиент переводит деньги со сберегательного счета на расчетный счет, транзакция должна состоять из трех отдельных операций:

  • Уменьшение сберегательного счета

  • Увеличение расчетного счета

  • Запись о транзакции в журнале транзакций

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

Следующий рисунок иллюстрирует банковскую транзакцию. Первая операция вычитает 500 долларов со сберегательного счета 3209. Вторая операция добавляет 500 долларов к текущему счету 3208. Третья инструкция вставляет запись о передаче в таблицу журнала. Заключительный оператор фиксирует транзакцию.

oracon_fig12_1

Структура транзакции

Транзакция БД состоит из одного или нескольких операторов.

В частности, транзакция состоит из одного из следующих действий:

  • Один или несколько операторов языка обработки данных (DML), которые вместе представляют собой атомарное изменение БД

  • Оператор языка определения данных (DDL)

Транзакция имеет начало и конец.

Начало транзакции

Транзакция начинается при выполнении первого исполняемого SQL-оператора.

Исполняемый SQL-оператор – это SQL-оператор, который генерирует вызовы экземпляра БД, включая инструкции DML и DDL и инструкцию SET TRANSACTION.

Когда транзакция начинается, БД Oracle назначает транзакцию доступному сегменту Undo, чтобы записать Undo-записи для новой транзакции. Идентификатор транзакции не выделяется до тех пор, пока не будут выделены Undo-сегмент и слот таблицы транзакций, что происходит во время первой инструкции DML. Идентификатор транзакции уникален для транзакции и представляет собой номер сегмента отмены, слот и порядковый номер.

В следующем примере выполняется инструкция UPDATE для начала транзакции и запрашивается V$TRANSACTION для получения подробной информации о транзакции:

SQL> UPDATE hr.employees SET salary=salary; 

107 rows updated.
 
SQL> SELECT XID AS "txn id", XIDUSN AS "undo seg", XIDSLOT AS "slot", 
  2  XIDSQN AS "seq", STATUS AS "txn status"
  3  FROM V$TRANSACTION;
 
txn id             undo seg       slot        seq txn status
---------------- ---------- ---------- ---------- ----------------
0600060037000000          6          6         55 ACTIVE

Окончание транзакции

Транзакция может завершиться при различных обстоятельствах.

Транзакция завершается, когда выполняется любое из следующих действий:

  • Пользователь выдает инструкцию COMMIT или ROLLBACK без указания SAVEPOINT.
    При фиксации пользователь явно или неявно запросил, чтобы изменения в транзакции стали постоянными. Изменения, внесенные транзакцией, являются постоянными и видны другим пользователям только после фиксации транзакции.

  • Пользователь запускает команду DDL, такую как CREATE, DROP, RENAME или ALTER.
    БД выдает неявный оператор COMMIT до и после каждого оператора DDL. Если текущая транзакция содержит инструкции DML, то Oracle Database сначала фиксирует транзакцию, а затем запускает и фиксирует инструкцию DDL как новую транзакцию с одним оператором.

  • Пользователь обычно завершает работу с большинством утилит и инструментов Oracle Database utilities, в результате чего текущая транзакция неявно фиксируется. Поведение фиксации при отключении пользователя зависит от приложения и настраивается.
    Примечание: Приложения всегда должны явно фиксировать или отменять транзакции перед завершением работы программы.

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

После завершения одной транзакции следующая исполняемая инструкция SQL автоматически запускает следующую транзакцию. В следующем примере выполняется UPDATE для запуска транзакции, завершается транзакция с помощью инструкции ROLLBACK, а затем выполняется UPDATE для запуска новой транзакции (обратите внимание, что идентификаторы транзакций разные):

SQL> UPDATE hr.employees SET salary=salary; 
107 rows updated.
 
SQL> SELECT XID, STATUS FROM V$TRANSACTION;
 
XID              STATUS
---------------- ----------------
0800090033000000 ACTIVE
 
SQL> ROLLBACK;
 
Rollback complete.
 
SQL> SELECT XID FROM V$TRANSACTION;
 
no rows selected
 
SQL> UPDATE hr.employees SET last_name=last_name;
 
107 rows updated.
 
SQL> SELECT XID, STATUS FROM V$TRANSACTION;
 
XID              STATUS
---------------- ----------------
0900050033000000 ACTIVE

Атомарность на уровне оператора

БД Oracle поддерживает атомарность на уровне оператора, что означает, что SQL-оператор является атомарной единицей работы и либо полностью выполняется успешно, либо завершается с ошибкой.

Успешный оператор отличается от зафиксированной транзакции. Один SQL-оператор выполняется успешно, если БД анализирует и запускает его без ошибок как атомарную единицу, например, когда все строки изменяются при многострочном обновлении.

Если SQL-оператор вызывает ошибку во время выполнения, значит, он не является успешным, и поэтому все последствия оператора отменяются. Эта операция представляет собой откат на уровне оператора. Эта операция имеет следующие характеристики:

  • Оператор SQL, который не выполняется успешно, приводит к потере только работы, которую он выполнил бы сам.
    Неудачное выполнение оператора не приводит к потере какой-либо работы, которая предшествовала ему в текущей транзакции. Например, если выполнение второго оператора по обновлению в “Примере транзакции: Дебет и кредит счета” вызывает ошибку и выполняется откат, то работа, выполненная первым оператором по UPDATE, не откатывается. Первая инструкция UPDATE может быть зафиксирована или откатана пользователем явно.

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

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

Номера системных изменений

Номер системного изменения (SCN) – это логическая внутренняя временная метка, используемая БД Oracle.

SCNs упорядочивают события, происходящие в БД, что необходимо для удовлетворения ACID-свойств транзакции. БД Oracle использует SCNs для пометки SCN, перед который, как известно, все изменения находятся на диске, чтобы избежать ненужного повтора при восстановлении. БД также использует SCNs для обозначения точки, в которой невозможен повтор для набора данных, чтобы можно было остановить восстановление.

SCN происходит в монотонно возрастающей последовательности. БД Oracle может использовать SCN как часы, поскольку наблюдаемый SCN указывает логический момент времени, а повторные наблюдения возвращают равные или большие значения. Если одно событие имеет более низкий SCN, чем другое событие, то оно произошло в БД в более раннее время. Несколько событий могут использовать один и тот же SCN, что означает, что они произошли в БД в одно и то же время.

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

БД Oracle увеличивает SCNs в глобальной области системы (SGA). Когда транзакция изменяет данные, БД записывает новый SCN в Undo-сегмент, назначенный транзакции. Затем процесс записи журнала немедленно записывает запись о фиксации транзакции в оперативный redo-журнал. Запись фиксации имеет уникальный SCN транзакции. Oracle Database также использует SCNs как часть своих механизмов восстановления экземпляров и носителей.

Обзор управления транзакциями

Управление транзакциями – это управление изменениями, вносимыми операторами DML, и группирование инструкций DML в транзакции.

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

Управление транзакциями предполагает использование следующих инструкций, как описано в разделе “Инструкции по управлению транзакциями”:

  • Оператор COMMIT завершает текущую транзакцию и делает все изменения, выполненные в транзакции, постоянными. COMMIT также стирает все точки сохранения в транзакции и снимает блокировки транзакций.

  • Оператор ROLLBACK отменяет работу, выполненную в текущей транзакции; это приводит к отбрасыванию всех изменений данных с момента последней COMMIT-а или ROLLBACK-а. Инструкция ROLLBACK TO SAVEPOINT отменяет изменения с момента последней точки сохранения, но не завершает всю транзакцию.

  • Оператор SAVEPOINT определяет в транзакции точку, к которой позже можно выполнить откат.

Сеанс, приведенный в таблице 12-1, иллюстрирует основные концепции управления транзакциями.

oracon_fig12_1a oracon_fig12_1b oracon_fig12_1c

Наименования транзакций

Имя транзакции – это необязательный, задаваемый пользователем тег, который служит напоминанием о работе, выполняемой транзакцией. Вы называете транзакцию с помощью оператора SET TRANSACTION ... NAME, который, если используется, должен быть первым оператором транзакции.

В таблице 12-1 первая транзакция была названа sal_update, а вторая – sal_update 2.

Именованная транзакция предоставляют следующие преимущества:

  • Проще мониторить длительные транзакции и разрешать сомнительные распределенные транзакции.

  • Можно просматривать имена транзакций вместе с идентификаторами транзакций в приложениях. Например, DBA может просматривать имена транзакций в Oracle Enterprise Manager (Корпоративный менеджер) при мониторинге активности системы.

  • БД записывает имена транзакций в redo-запись аудита транзакций, поэтому вы можете использовать LogMiner для поиска конкретной транзакции в redo-журнале.

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

Активные транзакции

Активной является транзакция, которая началась, но еще не зафиксирована или не откатана.

В таблице 12-1 первой операцией по изменению данных в транзакции sale_update является обновление заработной платы Banda. С момента успешного выполнения этого обновления до завершения транзакции оператором ROLLBACK транзакция sale_update активна.

Изменения данных, внесенные транзакцией, являются временными до тех пор, пока транзакция не будет зафиксирована или откатана. Перед завершением транзакции состояние данных будет таким, как показано в следующей таблице.

Таблица 12-2 Состояние данных перед завершением транзакции

Состояние Описание Подробности
БД Oracle сгенерировала undo-информацию в SGA. Undo-данные содержат старые значения данных, измененные SQL-операторами транзакции. Read Consistency in the Read Committed Isolation Level
БД Oracle сгенерировала redo в оперативном буфере redo-журнала SGA. Запись redo-журнала содержит изменение в блоке данных и изменение в undo. Redo Log Buffer
Были внесены изменения в буферы базы данных SGA. Изменения данных для зафиксированной транзакции, хранящиеся в буферах базы данных SGA, не обязательно немедленно записываются в файлы данных программой записи БД (DBW). Запись на диск может произойти до или после фиксации. Database Buffer Cache
Заблокированы строки, на которые повлияло изменение данных. Другие пользователи не могут изменять данные в затронутых строках и не могут видеть незафиксированные изменения. Summary of Locking Behavior

Точки сохранения

Точка сохранения – это объявленный пользователем промежуточный маркер в контексте транзакции.

Внутренне маркер точки сохранения преобразуется в SCN. Точки сохранения делят длительную транзакцию на более мелкие части.

Если вы используете точки сохранения в длительной транзакции, то позже у вас есть возможность откатить работу, выполненную до текущей точки транзакции, но после объявленной точки сохранения в транзакции. Таким образом, если вы допустите ошибку, вам не нужно повторно отправлять каждое утверждение. Таблица 12-1 создает точку сохранения after_banda_sal также для того, чтобы обновление зарплаты Greene можно было откатить до этой точки сохранения.

Откат к точке сохранения

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

Когда транзакция откатывается к точке сохранения, как при выполнении ROLLBACK TO SAVEPOINT after_banda_sal в таблице 12-1, происходит следующее:

  1. БД Oracle откатывает только инструкции, выполненные после точки сохранения.
    В таблице 12-1 ОТКАТ К ТОЧКЕ СОХРАНЕНИЯ приводит к откату ОБНОВЛЕНИЯ для Greene, но не ОБНОВЛЕНИЯ для Banda.

  2. БД Oracle сохраняет точку сохранения, указанную в инструкции ROLLBACK TO SAVEPOINT, но все последующие точки сохранения теряются.
    В таблице 12-1 ОТКАТ К ТОЧКЕ СОХРАНЕНИЯ приводит к потере точки сохранения after_greene_sal.

  3. БД Oracle освобождает все блокировки таблиц и строк, полученные после указанной точки сохранения, но сохраняет все блокировки данных, полученные до точки сохранения.

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

Очередь транзакций

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

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

В сценарии, показанном в следующей таблице, сеанс 1 выполняет откат к точке сохранения, созданной до выполнения инструкции DML. Однако сеанс 2 по-прежнему заблокирован, поскольку он ожидает завершения транзакции сеанса 1.

oracon_fig12_3a oracon_fig12_3b

Откат транзакции

Откат незафиксированной транзакции отменяет все изменения в данных, которые были выполнены SQL-операторами внутри транзакции.

После отката транзакции последствия работы, выполненной в транзакции, больше не существуют. При откате всей транзакции без ссылки на какие-либо точки сохранения БД Oracle выполняет следующие действия:

  • Отменяет все изменения, внесенные всеми SQL-операторами в транзакции, используя соответствующие сегменты Undo
    Запись таблицы транзакций для каждой активной транзакции содержит указатель на все Undo-данные (в обратном порядке применения) для транзакции. БД считывает Undo-данные, отменяет операцию, а затем помечает Undo-запись как примененную. Таким образом, если транзакция вставляет строку, то откат удаляет ее. Если транзакция обновляет строку, то откат отменяет обновление. Если транзакция удаляет строку, то откат повторно вставляет ее. В таблице 12-1 ОТКАТ отменяет обновления заработной платы Грина и Банды.

  • Освобождает все блокировки данных, удерживаемые транзакцией

  • Удаляет все точки сохранения в транзакции
    В таблице 12-1 при ОТКАТЕ удаляется точка сохранения after_banda_sal. Точка сохранения after_greene_sal была удалена с помощью инструкции ROLLBACK TO SAVEPOINT.

  • Завершает транзакцию
    В таблице 12-1 показано, что ОТКАТ оставляет БД в том же состоянии, в котором она была после выполнения первоначальной ФИКСАЦИИ.

Продолжительность отката зависит от объема измененных данных.

Фиксация транзакции

Фиксация завершает текущую транзакцию и делает постоянными все изменения, выполненные в транзакции.

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

Когда транзакция фиксируется, выполняются следующие действия:

  • БД генерирует SCN для ФИКСАЦИИ.
    Внутренняя таблица транзакций для связанного табличного пространства Undo записывает, что транзакция была зафиксирована. Соответствующий уникальный SCN транзакции присваивается и записывается в таблицу транзакций.

  • Процесс записи журнала (LGWR) записывает оставшиеся записи redo-журнала из буферов redo-журнала в оперативный redo-журнал и записывает SCN транзакции в оперативный redo-журнал. Это атомарное событие представляет собой фиксацию транзакции.

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

  • БД Oracle выполняет очистку фиксации.
    Если измененные блоки, содержащие данные из зафиксированной транзакции, все еще находятся в SGA, и если ни один другой сеанс не изменяет их, то БД удаляет из блоков информацию о транзакции, связанную с блокировкой (запись ITL).
    В идеале, COMMIT очищает блоки, чтобы последующему SELECT не приходилось выполнять эту задачу. Если для определенной строки не существует записи ITL, то она не заблокирована. Если запись ITL существует для определенной строки, то она, возможно, заблокирована, поэтому сеанс должен проверить заголовок undo-сегмента, чтобы определить, была ли зафиксирована эта заинтересованная транзакция. Если заинтересованная транзакция зафиксирована, то сеанс очищает redo-блок. Однако, если ФИКСАЦИЯ ранее очистила ITL, то проверка и очистка не нужны.
    Примечание: Поскольку очистка блока генерирует redo, запрос может сгенерировать redo и, таким образом, вызвать запись блоков во время следующей контрольной точки.

  • БД Oracle помечает транзакцию как завершенную.

После фиксации транзакции пользователи могут видеть изменения.

Как правило, фиксация – это быстрая операция, независимо от размера транзакции. Скорость фиксации не увеличивается с увеличением размера данных, измененных в транзакции. Самая длинная часть фиксации – это ввод-вывод с физического диска, выполняемый LGWR. Однако количество времени, затрачиваемого LGWR, сокращается, поскольку он постепенно записывает содержимое буфера redo-журнала в фоновом режиме.

Поведение по умолчанию заключается в том, что LGWR синхронно записывает redo в онлайн-журнал redo, а транзакции ожидают, пока буферизованный redo окажется на диске, прежде чем возвращать фиксацию пользователю. Однако для снижения задержки фиксации транзакции разработчики приложений могут указать, что запись redo должна выполняться асинхронно, чтобы транзакциям не нужно было ждать, пока redo будет на диске, и они могли немедленно вернуться из вызова ФИКСАЦИИ.

Обзор охранителя транзакций

Transaction Guard – это API, который приложения могут использовать для обеспечения идемпотентности транзакции, то есть способности БД сохранять гарантированный результат фиксации, который указывает, была ли транзакция зафиксирована и завершена. БД Oracle предоставляет API для JDBC thin, OCI, OCCI и ODP.Net .

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

Чтобы решить, отправлять ли транзакцию повторно или вернуть результат (зафиксированный или незафиксированный) клиенту, приложение должно определить результат транзакции-в-полете. До Oracle Database 12c сообщения о фиксации, возвращаемые клиенту, не были постоянными. Проверка транзакции не была гарантией того, что она не будет зафиксирована после проверки, что допускало дублирование транзакций и другие формы логического повреждения. Например, пользователь может обновить веб-браузер при покупке книги онлайн и получить двойную плату за одну и ту же книгу.

Преимущества охранителя транзакций

Начиная с Oracle Database 12c, Transaction Guard предоставляет приложениям инструмент для определения статуса транзакции в процессе выполнения после восстановимого сбоя.

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

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

Transaction Guard – это основная функция БД Oracle. Непрерывность работы приложения использует Transaction Guard для маскировки сбоев со стороны конечных пользователей. Без защиты транзакций повторная попытка приложения после ошибки может привести к фиксации повторяющихся транзакций.

Как работает охранитель транзакций

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

Сообщения о неверном коммите

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

Следующий рисунок представляет собой высокоуровневое представление взаимодействия между клиентским приложением и БД.

oracon_fig12_2

В стандартном случае фиксации БД фиксирует транзакцию и возвращает клиенту сообщение об успешном завершении. На рисунке 12-2 клиент отправляет инструкцию фиксации и получает сообщение о том, что связь не удалась. Этот тип сбоя может произойти по нескольким причинам, включая сбой экземпляра БД или отключение сети. В этом сценарии клиент не знает о состоянии транзакции.

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

Логический Transaction ID

Oracle Database решает проблему сбоя связи с помощью глобально-уникального идентификатора, называемого логическим идентификатором транзакции.

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

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

Протокол “единственной обработки” обеспечивает доступ к результату фиксации, требуя от БД выполнения следующего:

  • Ведёт логический идентификатор транзакции в течение периода хранения, согласованного для повторной попытки

  • Сохраняет логический идентификатор транзакции при фиксации

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

Прежде чем приложение сможет определить результат последней транзакции после исправляемой ошибки, приложение получает логический идентификатор транзакции, хранящийся на клиенте, используя Java, OCI, OCCI или ODP.Net API. Затем приложение вызывает процедуру PL/SQL DBMS_APP_CONT.GET_LTXID_OUTCOME с логическим идентификатором транзакции, чтобы определить результат последней отправки: зафиксировано (true или false) и завершено (true или false).

При использовании Transaction Guard приложение может воспроизводить транзакции, когда ошибка исправима и последняя транзакция в сеансе не была зафиксирована. Приложение может продолжить работу после завершения последней транзакции и пользовательского вызова. Приложение может использовать Transaction Guard для возврата клиенту известного результата, чтобы клиент мог принять решение о следующем действии.

Пример охранителя транзакций

В этом сценарии сообщение о фиксации теряется из-за исправимой ошибки.

Защита транзакций использует логический идентификатор транзакции для сохранения результата инструкции COMMIT, гарантируя, что результат транзакции известен.

oracon_fig12_3

На рисунке 12-3 БД информирует приложение о том, зафиксирована ли транзакция и завершен ли последний вызов пользователя. Затем приложение может вернуть результат конечному пользователю. Возможности заключаются в следующем:

  • Если транзакция зафиксирована и вызов пользователя завершен, то приложение может вернуть результат конечному пользователю и продолжиться.

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

  • Если пользовательский вызов не был зафиксирован, то приложение может вернуть эту информацию конечному пользователю или безопасно отправить повторно. Соблюдение протокола гарантировано. Когда статус фиксации возвращает значение false, фиксация последней отправки блокируется.

Смотри подробнее: Oracle Database Development Guide

Обзор непрерывности работы приложения

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

Обычно запрос соответствует операторам DML и другим вызовам БД одного веб-запроса при единственном подключении к БД. В общем случае запрос разграничивается вызовами, выполняемыми между извлечением и регистрацией подключения к БД из пула подключений.

Преимущества непрерывности работы приложения

Основная проблема для разработчиков заключается в том, как скрыть потерянный сеанс БД от конечных пользователей.

Application Continuity пытается решить проблему потерянного сеанса путем восстановления сеанса БД, когда какой-либо компонент прерывает диалог между БД и клиентом. Восстановленный сеанс БД включает в себя все состояния, курсоры, переменные и самую последнюю транзакцию, если таковая существует.

Варианты использования непрерывности работы приложения

В типичном случае клиент отправил запрос в БД, которая создала как транзакционные, так и нетранзакционные состояния.

Состояние на клиенте остается текущим, потенциально с введенными данными, возвращенными данными и кэшированными данными и переменными. Однако состояние сеанса БД, в пределах которого приложение должно работать, теряется.

Если запрос клиента инициировал одну или несколько транзакций, то приложение сталкивается со следующими возможностями:

  • Если был выдан COMMIT, то сообщение о фиксации, возвращенное клиенту, не является долговременным. Клиент не знает, зафиксирован ли запрос и в каком состоянии нетранзакционной обработки он был достигнут.

  • Если COMMIT не был принят или если был принят, но не был выполнен, то транзакция-в-полете откатывается и должна быть повторно отправлена с использованием сеанса в правильном состоянии.

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

Непрерывности работы приложения для планового сопровождения

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

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

Если Application Continuity включена, БД может выполнять следующее:

  • Сообщать во время технического обслуживания об отсутствии ошибок как для входящих, так и для существующих работ.

  • Перенаправлять активные сеансы БД на другие функциональные службы.

  • При необходимости производить перебалансировку сеансов БД данных во время и после технического обслуживания.

Во время планового технического обслуживания производится управление поведением с помощью служебных атрибутов drain_timeout и stop_option утилиты SRVCTL, Global Data Services Control Utility (GDSCTL) и Oracle Data Guard Broker. Пакет DBMS_SERVICE предоставляет базовую инфраструктуру.

Архитектура непрерывности работы приложения

Ключевыми компонентами непрерывности работы приложения являются среда выполнения, переподключение и повторное воспроизведение.

Этапы заключаются в следующем:

1. Обычное время выполнения
На этом этапе непрерывность работы приложения выполняет следующие задачи:

  • Идентифицирует запросы к БД

  • Решает, являются ли вызовы БД локальными или воспроизводимыми

  • Создает, при необходимости, прокси-объекты для разрешения воспроизводимости и для управления очередями

  • Удерживает исходные вызовы и проверку этих вызовов до тех пор, пока не будет завершен запрос к БД или пока воспроизведения запрещены

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

  • Убеждается, что разрешено воспроизведение запросов к БД

  • Управляет временем обработки запросов

  • Получает новое подключение к БД, а затем проверяет, что это допустимый целевой объект БД

  • Использует Transaction Guard для определения того, успешно ли была зафиксирована последняя транзакция (зафиксированные транзакции повторно не отправляются)

3. Повтор
Непрерывность работы приложения выполняет следующие задачи:

  • Воспроизводит вызовы, которые находятся в очереди

  • Отключает воспроизведение, если во время воспроизведения появляются видимые пользователем изменения в результатах

  • Не разрешает фиксацию, но позволяет последнему вызову (который столкнулся с ошибкой) произвести коммит

После успешного воспроизведения запрос продолжается с момента сбоя.

Обзор автономных транзакций

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

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

Автономные транзакции обладают следующими характеристиками:

  • Автономная транзакция не видит незафиксированных изменений, внесенных основной транзакцией, и не делится блокировками или ресурсами с основной транзакцией.

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

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

В PL/SQL автономная транзакция выполняется в автономной области, которая представляет собой процедуру, помеченную pragma AUTONOMOUS_TRANSACTION. В этом контексте подпрограммы включают анонимные блоки PL/SQL верхнего уровня, а также подпрограммы и триггеры PL/SQL. Прагма – это директива, которая предписывает компилятору выполнить параметр компиляции. Pragma AUTONOMOUS_TRANSACTION сообщает БД, что эта процедура при выполнении должна выполняться как новая автономная транзакция, независимая от своей родительской транзакции.

На следующем рисунке показано, как управление переходит от основной процедуры (MT) к автономной процедуре и обратно. Основная процедура – proc1, а автономная процедура – proc2. Автономная процедура может совершить несколько транзакций (AT1 и AT2), прежде чем управление вернется к основной процедуре.

Рис 12-4. Поток управления транзакциями

oracon_fig12_4

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

На рисунке 12-4 COMMIT внутри proc1 фиксирует не только свою собственную работу, но и любую незавершенную работу, выполненную в его сеансе. COMMIT внутри proc2 делает постоянной только работу, выполненную в транзакции proc2. Таким образом, инструкции COMMIT в транзакциях AT1 и AT2 не оказывают никакого влияния на транзакцию MT.

Обзор распределенных транзакций

Распределенная транзакция – это транзакция, которая включает в себя одну или несколько инструкций, которые обновляют данные на двух или более различных узлах распределенной БД, используя объект схемы, называемый DBLink.

Распределенная БД - это набор БД в распределенной системе, которые могут отображаться приложениями как единый источник данных. DBLink описывает, как один экземпляр БД может войти в другой экземпляр БД.

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

Двух-фазный COMMIT

Двухфазный механизм фиксации гарантирует, что все частичные БД, участвующие в распределенной транзакции, либо все фиксируют, либо все отменяют инструкции в транзакции. Этот механизм также защищает неявный DML выполняемый ограничениями целостности, удаленными вызовами процедур и триггерами.

При двухфазной фиксации между несколькими БД одна база данных координирует распределенную транзакцию. Инициирующий узел называется глобальным координатором. Координатор запрашивает другие БД, готовы ли они к фиксации. Если какая-либо БД отвечает “нет”, то вся транзакция откатывается. Если все БД проголосуют “за”, то координатор отправит сообщение, чтобы сделать фиксацию постоянной в каждой из БД.

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

Сомнительные транзакции

Сомнительная распределенная транзакция возникает, когда двухфазная фиксация была прервана каким-либо системным или сетевым сбоем.

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

Фоновый процесс recoverer (RECO) автоматически разрешает результаты сомнительных распределенных транзакций. После устранения сбоя и восстановления связи процесс RECO каждой локальной БД Oracle автоматически фиксирует или откатывает любые сомнительные распределенные транзакции последовательно на всех задействованных узлах.

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

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