Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция_6-15.doc
Скачиваний:
6
Добавлен:
01.03.2025
Размер:
1.43 Mб
Скачать

4.2.4Режимы транзакций — до 20 мин.

Транзакция может начинаться в одном из трех режимов: автофиксация (autocommit), явный режим (explicit) или неявный режим (implicit). По умолчанию для SQL Server принят режим автофиксации. Рассмотрим, что означает каждый из этих режимов.

В режиме автофиксации каждый оператор T-SQL фиксируется по его завершении, и в этом режиме не требуется никаких дополнительных операторов для управления транзакциями. Иными словами, каждая транзакция состоит только из одного оператора T-SQL. Режим автофиксации полезен при выполнении операторов с помощью интерактивной командной строки, утилиты OSQL или анализатора очередей SQL Server Query Аnalyzer, поскольку вам не нужно задавать в явном виде запуск и окончание каждой транзакции. Каждый оператор будет рассматриваться системой SQL Server как отдельная транзакция и будет фиксироваться сразу после его завершения. Режим автофиксации будет использоваться в каждом соединении с SQL Server, пока вы не запустите транзакцию в явном режиме с помощью оператора BEGIN TRANSACTION или пока не укажете неявный режим. По окончании явно заданной транзакции или после отключения неявного режима SQL Server возвращается к режиму автофиксации.

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

Использование явной транзакции

Рассмотрим ситуацию, в которой вам потребовалось бы использование явной транзакции для запуска и окончания задачи. Предположим, что у нас имеется хранимая процедура с именем Place_Order (Поместить_Заказ), которая управляет в базе данных задачей размещения заказа покупателя на какой-либо товар. Эта процедура включает в себя следующие шаги: выбор информации о текущем счете покупателя, ввод идентификационного номера нового заказа и наименования товара, расчет стоимости заказа с учетом налогов, обновление остатка на счете покупателя с учетом общей стоимости и проверка наличия товара на складе.

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

Использование явных транзакций, когда ваша задача состоит из нескольких шагов, как в предыдущем примере, также дает преимущества, поскольку 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] [имя_транзакции | @переменная_с_именем_транзакции

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

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

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

Все ресурсы, используемые транзакцией, такие как блокировки, освобождаются после фиксирования данной транзакции. Фиксирование транзакции считается успешным в случае успешного завершения каждого из ее операторов. Ниже приводится небольшая транзакция с именем update_state, которая изменяет в таблице publishers (издатели) значение колонки state на XX для всех издателей, у которых в этой колонке содержится значение NULL:

USE pubs

GO

BEGIN TRAN update_state

UPDATE publishers SET state = 'XX'

WHERE state IS NULL

COMMIT TRAN update_state

GO

Запустив эту транзакцию, вы увидите, что это повлияло на две строки. Чтобы вернуть таблицу к ее исходному состоянию (как если бы вместо фиксирования произошел откат), выполните следующую транзакцию:

USE pubs

GO

BEGIN TRAN undo_update_state

UPDATE publishers SET state = NULL

WHERE state = 'XX'

COMMIT TRAN undo_update_state

GO

И снова вы увидите, что это повлияло на две строки. Имена транзакций update_state (модифицировать_состояние) и undo_update_state (отменить_модификацию_состояния), используемые в операторе COMMIT TRAN, игнорируются в SQL Server: имена транзакций используются просто для удобства программиста, чтобы можно было указать имя фиксируемой транзакции. SQL Server автоматически фиксирует последнюю нефиксированную транзакцию, запущенную перед фиксированием, независимо от указания имени транзакции.

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

В неявном режиме транзакция автоматически начинается при использовании определенных операторов 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, то с него начинается новая транзакция в неявном режиме, и соответствующие ресурсы не будут освобождены, пока не будет фиксирована эта транзакция.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]