Управление транзакциями в среде MS SQL Server
Что такое транзакция?
Транзакция — это набор операций, которые выполняются в базе данных как один логический блок. При использовании транзакций, SQL Server позволяет обеспечить целостность данных, и возможность восстановить удаленные или измененные данные. SQL Server использует внутренний журнал транзакций для возможности восстановления данных в случае произошедших ошибок или отказов системы.
Целостность самой транзакции зависит от программиста. Он должен правильно определить, когда следует начать и когда закончить транзакцию, в какой последовательности выполнять операции в транзакции, чтобы обеспечить логическую последовательность и содержательность данных.
Определение транзакций
Существует несколько способов управления поведением транзакций. При этом пользователь должен указать только начало и конец транзакции. Транзакции определяются на уровне одного соединения с базой данных, и при закрытии этого соединения, автоматически закрываются. После того, как транзакция открыта, все команды, которые описаны внутри ее, выполняются как единое целое, пока не будет достигнут конец транзакции.
СУБД MS SQL Server поддерживает три вида транзакций:
• явное;
• автоматическое;
• подразумеваемое.
Если тип транзакции не указан явно, то по умолчанию используется режим автоматического определения начала и конца транзакции, при котором каждая команда рассматривается сервером как отдельная транзакция. Если указанные команды в транзакции выполняются успешно, то все внесенные в базу данных изменения фиксируются. Если же при выполнении команд произошли ошибки или сбои, то все сделанные изменения в базе отменяются.
Если необходимо передать серверу базы данных несколько команд внутри одной транзакции, то следует явно указать тип транзакции. Чтобы установить режим автоматического определения транзакций, необходимо выполнить команду:
SET IMPLICIT_TRANSACTIONS OFF
Если используется режим подразумевающегося начала транзакции, то сервер автоматически будет начинать новую транзакцию, только после того, как будет завершена предыдущая. Чтобы включить данный режим, используют команду:
SET IMPLICIT_TRANSACTIONS ON
Явные транзакции
При использовании режима явных транзакций, пользователь обязан самостоятельно указать серверу начало и конец транзакции. При этом запрос к базе данных имеет следующий вид:
• Начало транзакции. Чтобы открыть транзакцию, запрос должен начинаться с команды:
BEGIN TRAN[SACTION]
[имя_транзакции |
@имя_переменной_транзакции
[WITH MARK [‘описание_транзакции’]]]
• Конец транзакции. Если в процессе обработки запроса, не было ошибок, то конец транзакции указывает серверу зафиксировать внесенные изменения и закрыть соединение с базой данных. Конец транзакции определяется при помощи команды:
COMMIT [TRAN[SACTION]
[имя_транзакции |
@имя_переменной_транзакции]]
• Если в процессе выполнения команд внутри транзакции необходимо создать точку сохранения, используют команду:
SAVE TRAN[SACTION]
{имя_точки_сохранеия |
@имя_переменной_точки_сохранения}
• Чтобы прервать транзакцию и откатить результаты выполнения команд на изменение данных в базе данных, используют команду:
ROLLBACK [TRAN[SACTION]
[имя_транзакции |
@имя_переменной_транзакции
| имя_точки_сохранения
|@имя_переменной_точки_сохранения]]
При этом восстанавливается первоначальное состояние базы данных, и в журнале транзакций ставится пометка, что транзакция была отменена. Если в базе данных была создана точка сохранения, то отменяются все изменения данных, которые были внесены после создания данной точки.
Используя функцию @@TRANCOUNT, можно узнать количество активных транзакций. Чтобы узнать уровень вложенности транзакции, используют функцию @@NESTLEVEL.
Вложенные транзакции
Транзакция считается вложенной, если она была вызвана из тела другой, уже активной транзакции. Чтобы создать вложенную транзакцию, не нужно использовать какие-либо дополнительные команды. Для вызова вложенной транзакции, достаточно описать ее в том месте, где предполагается ее вызов. Транзакция не будет завершена до тех пор, пока не будут выполнены все вложенные в нее транзакции. Если транзакция самого нижнего уровня завершается с ошибкой, и внесенные ей изменения отменены, то отменяются все действия, которые были внесены транзакцией, включая самый верхний ее уровень. Более того, если все транзакции нижнего уровня завершены успешно, но данные не были зафиксированы, то при ошибочном завершении транзакции среднего уровня (не самого верхнего) вызовет отмену всей транзакции, включая те, которые завершились успешно.
Транзакция считается завершенной успешно только в том случае, если все вложенные транзакции были завершены успешно. После успешного завершения транзакции самого верхнего уровня происходит фиксация всех сделанных транзакцией изменений.
Давайте рассмотрим пример вложенных транзакций в СУБД MS SQL Server:
BEGIN TRAN
INSERT Товар (Название, остаток)
VALUES (‘v’,40)
BEGIN TRAN
INSERT Товар (Название, остаток)
VALUES (‘n’,50)
BEGIN TRAN
INSERT Товар (Название, остаток)
VALUES (‘m’,60)
ROLLBACK TRAN