К настоящему моменту у вас уже должно быть чувство уверенности по поводу вида операций многопользовательской системы, как серии атомарных задач, изолированных в транзакциях. Задачи будут выполнены, когда клиенты запускают транзакции и когда клиенты их завершают. Помимо конфигурирования транзакции для задания задаче условий доступа, изоляции и способа разрешения блокировок, клиент имеет другие возможности для взаимодействия с транзакцией в процессе ее выполнения. На рис. 27.1 показаны подобные точки этого взаимодействия. В остальных разделах настоящей главы более подробно рассматриваются техника и реализация таких задач.
Вложенные транзакции
В Firebird транзакции всегда запускаются и завершаются клиентом. Некоторые другие СУБД могут запускать и подтверждать транзакции из хранимых процедур, потому что для управления транзакциями они используют двухфазную блокировку транзакций. Вместо этого Firebird предоставляет другие механизмы, которые могут оперировать с потоком работы в транзакции без нарушения атомарности. Два из этих механизмов, блоки обработчика исключений и выполняемые строки, ограничены по использованию только в модулях PSQL и обсуждаются в части VII. Другим механизмом, недоступным в PSQL, являются пользовательские точки сохранения.
Рис. 27.1. Взаимодействие приложения и транзакции
! ! !
ПРИМЕЧАНИЕ. Выполняемые строки и пользовательские точки сохранения являются новыми возможностями, добавленными в язык в Firebird 1.5.
. ! .
Пользовательские точки сохранения
Операторы пользовательских точек сохранения (user savepoints), также называемые вложенными транзакциями, позволяют вам "упаковать" группы операций внутри транзакции и отмечать их, если пересылка в базу данных была успешной. Если позже в последовательности задач появится исключение, транзакция может выполнить откат к последней точке сохранения. Операции, отправленные в базу между этой точкой сохранения и возникшим исключением, будут отменены, а приложение может выполнить корректировку, подтверждение, полный откат, продолжить работу - в зависимости от того, что требуется сделать.
Пользовательские точки сохранения являются операцией клиентской стороны, доступной только в операторах DSQL.
Оператором создания пользовательской точки сохранения является:
SAVEPOINT <идентификатор>;
Идентификатор может быть любым правильным идентификатором SQL Firebird (максимум 31 алфавитно-цифровой символ ASCII, уникальный в транзакции). Вы можете заново использовать тот же идентификатор в той же транзакции, он перекроет существующую точку сохранения, связанную с этим именем.
Возврат (или откат, rollback) на точку сохранения начинается с отмены всей работы, выполненной и отправленной в базу данных после создания этой точки сохранения. Указанная точка сохранения и все предшествующие ей сохраняются. Любые точки сохранения, которые были созданы после указанной точки сохранения, пропадают.
Любые блокировки (явные и неявные), которые были установлены с момента создания указанной точки сохранения, будут сняты. При этом транзакции, которые были заблокированы при ожидании доступа к освобожденным строкам, все еще не получат к ним доступ, пока не завершится текущая транзакция. Это гарантирует, что ожидающие в настоящий момент конкуренты не повлияют на поток работы, когда он будет возобновлен. Все это не повлияет на транзакции, которые не находились в состоянии ожидания в момент вложенного отката.
Вот шаблон синтаксиса для отката на точку сохранения:
ROLLBACK [WORK] ТО [SAVEPOINT] <идентификатор>;
Если транзакция позволяет продолжить работу после отката на точку сохранения, то в дальнейшем работа может осуществлять откат на эту точку сохранения столько раз, сколько потребуется. Версии записей, которые были отменены откатом, не будут доступны для сборщика мусора, потому что транзакция все еще является активной.
Механизм реализации точек сохранения на сервере - протокол в памяти - может требовать значительного количества ресурсов, особенно если одни и те же строки изменяются многократно в процессе выполнения задачи. Ресурсы уже ненужных точек сохранения могут быть освобождены при использовании оператора RELEASE
SAVEPOINT:
RELEASE SAVEPOINT <идентификатор> [ONLY];
Без ключевого слова ONLY указанная точка сохранения и все точки сохранения, которые были созданы после нее, будут освобождены и потеряны. Используйте ONLY для освобождения только указанной точки сохранения.
Следующий пример иллюстрирует работу точек сохранения:
CREATE TABLE SAVEPOINT_TEST (ID INTEGER);
COMMIT;
INSERT INTO SAVEPOINT_TEST
VALUES(99);
COMMIT;
INSERT INTO SAVEPOINT_TEST
VALUES(100) ;
/**/
SAVEPOINT SP1;
/**/
DELETE FROM SAVEPOINT_TEST;
SELECT * FROM SAVEPOINT_TEST; /* не вернет ничего */
/**/
ROLLBACK TO SP1;
/**/
SELECT * FROM SAVEPOINT_TEST; /* вернет 2 строки */
ROLLBACK;
/**/
SELECT * FROM SAVEPOINT_TEST;
/* вернет одну подтвержденную строку */