Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
бд 18-21 (или 17-20).doc
Скачиваний:
6
Добавлен:
26.04.2019
Размер:
233.47 Кб
Скачать

Вопрос 19

Транзакции. Свойства транзакций ACID. Явные и неявные транзакции. Команды SQL для управления транзакциями (begin, commit, rollback). Понятие точек сохранения (savepoints). Модели транзакций в СУБД: линейные и вложенные транзакции.

Что такое транзакция?

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

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

ACID-свойства

Чтобы транзакцию можно было считать допустимой для использования, она должна отвечать четырем требованиям. Эти требования называют ACID-свойствами. "ACID" – это сокращение от "atomicity (атомарность), consistency (согласованность), isolation (изолированность) и durability (устойчивость)". В SQL Server включены механизмы, помогающие обеспечивать соответствие транзакций каждому из этих требований.

Атомарность

SQL Server обеспечивает, что в случае успешного выполнения транзакции фиксируются все модификации данных этой транзакции (в виде группы), а в случае неудачного выполнения транзакции не фиксируется ни одна из модификаций; иными словами, SQL Server обеспечивает атомарность своих транзакций. Транзакция должна выполняться как элементарная (атомарная) операция – отсюда термин "атомарность". Чтобы транзакция считалась успешно выполненной, должен быть выполнен каждый шаг (или оператор) этой транзакции. При неудачном выполнении одного из шагов вся транзакция считается неуспешной, и происходит отмена всех модификаций, внесенных с момента начала транзакции. SQL Server содержит механизм управления транзакциями, который автоматически определяет результат завершения транзакции (успешный или неуспешный) и при необходимости (в случае неуспешной транзакции) отменяет любые модификации данных.

Согласованность

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

Согласованность также является свойством в управлении транзакциями, которое поддерживается в SQL Server. Если ваши данные являются согласованными, а в ваших транзакциях поддерживается логическая согласованность и целостность данных, то SQL Server обеспечит согласованность данных после любой транзакции. Используя репликацию данных в распределенной среде, вы можете задавать различные уровни согласованности от конечной сходимости транзакций, т.е. скрытой согласованности, до непосредственной согласованности транзакций. Уровень согласованности будет зависеть от типа используемой вами репликации. Более подробную информацию о репликациях см. в лекциях 26, 27 и 28.

Изолированность

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

Устойчивость

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

Явный режим

Явный режим используется чаще всего для программных приложений, а также для хранимых процедур, триггеров и сценариев. При запуске группы операторов для выполнения какой-либо задачи вам может потребоваться указание начала и конца данной транзакции, чтобы затем выполнить фиксацию всей группы операторов или отмену (откат) модификаций всей группы. Если вы явно указываете начало и конец транзакции, это означает, что вы используете явный режим, и такую транзакцию называют явной транзакцией. Явная транзакция задается с помощью операторов T-SQL или с помощью функций API. В этом разделе рассматривается только метод T-SQL; функции API выходят за рамки изложения этой книги.

Использование явных транзакций, когда ваша задача состоит из нескольких шагов, как в предыдущем примере, также дает преимущества, поскольку SQL Server (независимо от использования вами операторов ROLLBACK) автоматически выполнит откат ваших транзакций в случае серьезных ошибок, таких как обрыв связи в сети, аварийный сбой (базы данных или клиентской системы) или взаимоблокировка. (Взаимоблокировки рассматриваются в разделе "Блокирование и взаимоблокировки" далее.) Для запуска транзакции используется оператор T-SQL BEGIN TRANSACTION. Чтобы указать конец транзакции, используется COMMIT TRANSACTION или ROLLBACK TRANSACTION. В операторе BEGIN TRANSACTION вы можете дополнительно указать имя транзакции и затем ссылаться на эту транзакцию по имени в операторе COMMIT TRANSACTION или ROLLBACK TRANSACTION. Ниже показан синтаксис этих трех операторов:

BEGIN TRAN[SACTION] [имя_транзакции | @переменная_с_именем_транзакции]

COMMIT [TRAN[SACTION] [имя_транзакции | @переменная_с_именем_транзакции]]

ROLLBACK [TRAN[SACTION] [имя_транзакции | @переменная_с_именем_транзакции

| имя_точки_сохранения | @переменная_с_именем_точки_сохранения]]

Неявный режим

В неявном режиме транзакция автоматически начинается при использовании определенных операторов T-SQL и продолжается, пока не появится оператор явного окончания COMMIT или ROLLBACK. Если оператор окончания не указан, то при отсоединении пользователя происходит откат данной транзакции. Следующие операторы T-SQL являются началом новой транзакции в неявном режиме:

ALTER TABLE

CREATE

DELETE

DROP

FETCH

GRANT

INSERT

OPEN

REVOKE

SELECT

TRUNCATE TABLE

UPDATE

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

Чтобы задать неявный режим транзакций, вы можете использовать следующий оператор T-SQL:

SET IMPLICIT_TRANSACTIONS {ON | OFF}

Значение ON активизирует неявный режим, и OFF отключает его. После отключения неявного режима используется режим автофиксации.

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

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

Вы можете избежать отката всей транзакции; для этого нужно использовать точку сохранения, которая позволяет выполнять откат только до определенной точки в транзакции, а не до самого начала транзакции. Все модификации, выполненные до точки сохранения, остаются в силе и не подвергаются откату; но для всех операторов, выполняемых после точки сохранения (которую вы должны указать в транзакции) вплоть до оператора ROLLBACK, будет выполнен откат. Затем начнут выполняться операторы, следующие за оператором ROLLBACK. Если вы затем зададите откат транзакции без указания точки сохранения, то, как обычно, будет выполнен откат всех модификаций вплоть до начала данной транзакции, т.е. будет отменена вся транзакция. Отметим, что при откате транзакции до точки сохранения SQL Server не освобождает блокированные ресурсы. Они будут освобождены после фиксирования транзакции или после отката всей транзакции.

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

SAVE TRAN[SACTION] {имя_точки_сохранения | @переменная_с_именем_точки_сохранения}

Поместите точку сохранения в том месте транзакции, до которого вы хотите выполнять откат. Чтобы выполнить откат до точки сохранения, используйте ROLLBACK TRAN вместе с именем точки сохранения, как это показано ниже:

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

Вы можете использовать другие операторы T-SQL, чтобы продолжить транзакцию. Не забудьте включить оператор COMMIT или другой оператор ROLLBACK после первого оператора ROLLBACK, чтобы завершить всю транзакцию.

В SQL Server разрешаются вложенные транзакции, т.е. транзакции внутри транзакции. В случае вложенных транзакций вы должны явно фиксировать каждую внутреннюю транзакцию, чтобы SQL Server получал информацию об окончании внутренней транзакции и мог освободить ресурсы, используемые этой транзакцией, когда будет фиксирована внешняя транзакция. Если ресурсы блокированы, другие пользователи не могут получать доступа к этим ресурсам. Хотя вы должны явным образом включать оператор фиксации COMMIT для каждой транзакции, SQL Server не выполняет фактического фиксирования внутренних транзакций, пока не произойдет успешное фиксирование внешней транзакции; одновременно с этим SQL Server освобождает все ресурсы, используемые внутренними и внешней транзакциями. При неуспешном фиксировании внешней транзакции фиксирование внутренних транзакций не выполняется и происходит откат внешней и всех внутренних транзакций. После фиксирования внешней транзакции выполняется фиксирование внутренних тр анзакций. Иными словами, SQL Server по сути игнорирует операторы COMMIT внутри внутренних вложенных транзакций – в том смысле, что внутренние транзакции не фиксируются в ожидании окончательного фиксирования или отката внешней транзакции, чтобы определить статус завершения всех внутренних транзакций. (Это разъясняется в примерах на врезках "Практические советы" далее.) Кроме того, в случае использования оператора отката ROLLBACK во внешней транзакции или в любой из внутренних транзакций происходит откат всех этих транзакций. В оператор ROLLBACK нельзя включать имя внутренней транзакции; в этом случае SQL Server возвратит сообщение об ошибке. Можно включать имя внешней транзакции, имя точки сохранения или не включать никакого имени. (Описание точек сохранения приводится в разделе "Точки сохранения" далее.)