Как мы отмечали в начале этого раздела, транзакции могут инициироваться как явным способом (с помощью оператора START TRANSACTION), так и неявно, при выполнении первого оператора, требующего наличия контекста транзакции. Для завершения транзакции всегда1) требуется выполнение одного из двух операторов COMMIT (фиксация транзакции) или ROLLBACK (откат транзакции), которые имеют следующий синтаксис:
COMMIT [ WORK ] [ AND [ NO ] CHAIN ] ROLLBACK [ WORK ] [ AND [ NO ] CHAIN ] [ TO SAVEPOINT savepoint_name ]
При желании завершить транзакцию таким образом, чтобы все произведенные ею изменения были навсегда сохранены в базе данных, следует завершать транзакцию оператором COMMIT (как видно из синтаксиса, допускается эквивалентный вид COMMIT WORK). Если требуется завершить транзакцию с аннулированием всех произведенных изменений, то нужно использовать оператор ROLLBACK (ROLLBACK WORK).
Заметим, что и операция фиксации транзакции, и операция отката являются достаточно сложными и выполняются не мгновенно. Поэтому в ходе выполнения этих операций, вообще говоря, может произойти аварийный отказ системы. Естественно (хотя в этом курсе мы не обсуждаем технические детали возможных реализаций), база данных будет восстановлена в свое последнее согласованное состояние, но ситуации прерванного выполнения операции фиксации и операции отката коренным образом различаются. Оператор COMMITсчитается безусловно выполненным только в том случае, когда сервер баз данных подтвердил это после выполнения всех действий, требуемых для фиксации транзакции. Аварийная ситуация во время выполнения операции ROLLBACK ничем не отличается от аварийной ситуации, возникшей в процессе выполнения транзакции. В этом случае (при восстановлении базы данных) прерванная транзакция считается незафиксированной (что так и есть), и все ее изменения автоматически удаляются из состояния базы данных. Поэтому окончательный результат выполнения операции фиксации транзакции, прерванной аварийным отказом системы, эквивалентен успешному выполнению операции отката транзакции2).
Синтаксис обоих операторов показывает, что в каждом из них может содержаться раздел AND [ NO ] CHAIN. Постараемся кратко пояснить смысл этого раздела (не вдаваясь в детали, поскольку стандарт SQL:1999 оставляет окончательное решение за реализацией).
Операции образования и завершения транзакции являются достаточно дорогостоящими. В особенности это касается операции завершения транзакции, при выполнении которой необходимо выполнить обмены с внешней памятью. С другой стороны, использование долговременных транзакций чревато снижением уровня параллелизма в системе, а также повышает риск утраты результатов транзакции в результате системного отказа.
Поэтому часто используется компромиссный вариант, при котором действия операторов COMMIT или ROLLBACK приводят не только к завершению текущей транзакции, но и к образованию новой транзакции3). Именно эту возможность поддерживает раздел AND [ NO ] CHAIN операторов COMMIT и ROLLBACK. Если такой раздел отсутствует в операторе завершения транзакции, то подразумевается наличие раздела AND NO CHAIN, и новая транзакция не образуется. Если же раздел AND CHAIN присутствует, то немедленно после завершения выполнения COMMIT или ROLLBACK текущей транзакции образуется новая транзакция, наследующая все характеристики завершенной транзакции.
Семантику раздела TO SAVEPOINT мы поясним немного позже.