Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базы данных Язык SQL.doc
Скачиваний:
0
Добавлен:
29.12.2019
Размер:
1.36 Mб
Скачать

5.2.2 Поддержка транзакций в языке sql

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

Языковые правила поддержки транзакций для различных СУБД несколько различаются. Например, в Microsoft SQL Server поддерживается команда начала транзакции BEGIN TRANS[ACTION]. В Oracle такой команды нет, но существуют четкие правила, регламентирующие моменты начала и завершения транзакции:

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

COMMIT

команда DDL

COMMIT

Получается, что несколько команд DDL нельзя объединить в единую транзакцию и откатить команду DDL при помощи стандартной команды ROLLBACK в Oracle также нельзя.

2). Результаты выполнения команд dml автоматически фиксируются только при включенном режиме AUTOCOMMIT (например, в настройках утилиты SQL*Plus есть возможность включения этого режима). По умолчанию этот режим отключен. Таким образом, все идущие подряд команды DML воспринимаются как одна транзакция.

Инициализация транзакции (неявная команда BEGIN TRANSACTION) происходит в следующих случаях:

  • первая команда в сеансе связи

  • первая команда после команд COMMIT или ROLLBACK

  • первая команда после команды DDL

Завершение транзакции происходит при поступлении команд commit (завершение транзакции с фиксацией изменений) или rollback (завершение транзакции с откатом изменений). Можно неявно зафиксировать команду транзакцию из последовательности команд dml любой следующей за ней командой ddl.

Стандарт SQL и многие СУБД, в том числе Oracle, предусматривают так называемые точки сохранения. Точка сохранения задается оператором

SAVEPOINT имя_точки_сохранения

и в операторе ROLLBACK имеется возможность отката транзакции не к началу, а к указанной точке сохранения:

ROLLBACK TO имя_точки_сохранения

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

5.2.3 Механизмы субд для поддержки транзакций

Поддержка транзакций требует значительных ресурсов и существенно (во много раз!) замедляет производительность сервера. Однако в современных условиях допустить потерю или порчу информации в базе данных абсолютно недопустимо, поэтому правила АСИД реализуются всеми СУБД. Несмотря на особенности конкретных реализаций, имеется ряд универсальных механизмов поддержки транзакций.

Мы рассмотрим эти обшие механизмы, добавив немного конкретных сведений по их воплощению в Oracle.

Журнализация транзакций

Ведение журналов транзакций преследует одновременно две цели:

1). Возможность отката транзакции.

2). Восстановление БД в случае аварийных ситуаций или сбоев.

Сервер ведёт 2 вида журналов транзакций:

Undo-журналы:

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

В Oracle такие журналы иначе называются сегментами отката, они располагаются в отдельном табличном пространстве и содержат полную информацию о каждой транзакции, достаточную для ее успешного отката. Рекомендуемое количество Undo журналов в базе данных, которые должны быть в наличии, равно n/2 (где n – количество одновременно работающих пользователей).

Redo-журнал

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

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

Такой механизм полностью гарантирует выполнение правила Долговечность из аббревиатуры АСИД. Для того, чтобы гарантировать возможность безусловного восстановления всех зафиксированных транзакций, принято правило упреждающей записи в журнал транзакций – по команде COMMIT результаты транзакции сначала заносятся в Redo-журнал, а потом (возможно не сразу), записываются в табличное пространство.

Кратко рассмотрим, как организовано ведение системного журнала транзакций в Oracle. С учетом огромного количества информации, которая постоянно записывается в этот журнал в процессе нормальной работы информационной системы, он состоит из двух частей – оперативной и архивной. Оперативная часть, в свою очередь, содержит два журнала (для повышения надежности каждый из журналов обычно ведется в двух экземплярах). В каждый момент времени один из журналов заполняется информацией о транзакциях сервера, а другой в это время копируется в архивный журнал, который организован на отдельном носителе большого объема. Этот процесс схематически показан на рис. 5.2

Рис. 5.2 – заполнение журнала транзакций в Oracle

Сериальный график исполнения транзакций. Монитор транзакций

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

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

Механизмы блокировки ресурсов рассмотрим отдельно.

Механизмы блокировки

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

Рассмотрим кратко, как организованы блокировки в Oracle.

Во-первых, объектом блокирования может быть вся таблица или отдельная строка, поэтому различают блокировки типа T (Table) или R (Row). Объектом блокирования в исключительных случаях может быть и вся база данных, но при обычной многопользовательской работе этого не допускают.

Во-вторых, поддерживается не только полная блокировка ресурса (эксклюзивная блокировка – обозначается как X-блокировка), но и разделяемая (Shared) блокировка (обозначается как S-блокировка). Разделяемая блокировка позволяет нескольким транзакциям одновременно использовать ресурс, но пока не снята разделяемая блокировка, сервер не может наложить на этот ресурс эксклюзивную блокировку.

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

Команды CREATE/ALTER/DROP TABLE накладывают эксклюзивную блокировку на уровне таблицы (блокировка TX). Это значит, что нельзя выполнять никаких действий над таблицей, пока не будет закончена соответствующая операция DDL. Очевидно, для команд DDL и фиксация выполняет автоматически с целью быстрее освободить таблицу от эксклюзивной блокироки.

Команды INSERT/DELETE/UPDATE используют ресурсы в более мягком режиме. Каждая из этих команд накладывает эксклюзивную блокировку только на ту строку, которую она в данный момент обрабатывает (блокировка RX). Однако одновременно накладывается эксклюзивная блокировка на всю таблицу (блокировка TS), и это означает, что никакая DDL операция не может быть выполнена над таблицей до тех пор, пока не закончатся все DML-операции над этой таблицей и не будет снята последняя TS-блокировка (при нормальной работе такое случится, скорее всего, только к концу рабочего дня или в обеденный перерыв).

Команда SELECT не накладывает никакой блокировки на те таблицы, данные из которых она выбирает. Сервер Oracle гарантирует каждой команде выборки неизменность данных таблиц в процессе ее выполнения. Если в процессе выполнения какой-нибудь объемной и протяженной по времени выборки успела зафиксироваться какая-либо транзакция обновления данных, команда выборки не увидит результаты этой транзакции.