Шрифт:
Тот же самый идентификатор транзакции остается активным в TSB и никогда не становится "подтвержденным". По этой причине такое действие часто называется мягким подтверждением (soft commit) по сравнению с "жестким" подтверждением, выполняемым немодифицированным оператором COMMIT.
Каждое мягкое подтверждение похоже на точку сохранения без возможности возврата к ней. Все последующие операторы ROLLBACK отменяют только те изменения, которые были отправлены на сервер после последнего мягкого подтверждения.
Преимущество мягкого подтверждения в том, что оно облегчает жизнь программиста, особенно тех, кто использует компоненты, которые реализуют поведение "прокручиваемой базы данных". Это было сделано для поддержки сетки данных (grid) в пользовательском интерфейсе, используемой многими пользователями среды разработки Borland Delphi (и C++ Builder). Сохраняя контекст транзакции, приложение может отображать плавный переход состояния до-и-после, что сокращает работу программиста, которому иначе пришлось бы стартовать новые транзакции, открывать новые курсоры и заново синхронизировать их с наборами строк, хранящимися на клиенте.
Различные реализации доступа к данным часто объединяют пересылку на сервер единичного изменения, добавления или удаления с немедленным COMMIT RETAIN В механизм, дублирующий "автоподтверждение". Общим для уровней интерфейса является реализация возможности автоподтверждения для "молчаливого" управления транзакцией, запуская транзакцию невидимо для программиста в ситуациях, когда написанный программистом код пытается передавать оператор без предварительного старта транзакции.
Явное управление транзакциями стоит дополнительных усилий, особенно если вы применяете продукт, использующий такие гибкие средства, которые предоставляет Firebird. В загруженном работой окружении вариант COMMIT RETAIN может сократить время выполнения и ресурсы, однако он имеет некоторые серьезные недостатки.
* Транзакция SNAPSHOT продолжает хранить первоначальный образ базы данных, что означает, что пользователь не видит подтвержденных результатов других транзакций, которые ожидали подтверждения при старте текущей транзакции.
* Пока та же транзакция продолжает выполнять подтверждение в варианте RETAIN, ресурсы, используемые на сервере, не освобождаются, что приводит к чрезмерному росту ресурсов памяти, потребляемых TSB. Этот рост сильно ухудшает производительность, в конечном счете "замораживая" сервер, и при неблагоприятных условиях операционной системы даже может привести к краху системы.
* Никакие старые версии записей, ставшие устаревшими в результате операций, подтвержденных в транзакциях COMMIT RETAIN, не могут быть включены в сборку мусора, т. к. исходная транзакция никогда не выполняет "жесткого подтверждения".
Как и COMMIT, оператор ROLLBACK освобождает ресурсы на сервере и завершает физический контекст транзакции. При этом вид состояния базы данных в приложении возвращается к тому виду, как если бы эта транзакция никогда не стартовала. В отличие от COMMIT данный оператор никогда не завершается с ошибкой.
В логическом контексте "задачи" клиента после отката транзакции ваше приложение должно предоставить пользователю средства для разрешения проблем, которые вызвали исключение, и для повторного запуска новой транзакции.
SQL в Firebird не реализует синтаксис RETAIN В ROLLBACK так же, как это делается в COMMIT. При этом похожий механизм клонирования реализован в функции API isc_roiiback_retaining. Она восстанавливает для приложения вид базы данных в то состояние, которое было, когда транзакция получила дескриптор или, в случае транзакции READ COMMITTED, в то состояние, которое было при последнем вызове
isc_roiiback_retaining. Выделенные для транзакции системные ресурсы не освобождаются, курсоры сохраняются.
ROLLBACK RETAIN имеет те же самые ловушки, что и COMMIT RETAIN - и даже больше. Поскольку отдельные вызовы откатов производятся в ответ на исключение некоторого вида, сохранение контекста транзакции также сохранит и причины исключения. ROLLBACK RETAIN не должен использоваться в тех случаях, если существует шанс, что ваш последующий код обработки исключения не найдет и не исправит наследуемое исключение. Любые последующие ошибки ROLLBACK RETAIN должны обрабатываться с полным откатом транзакции для освобождения ресурсов и устранения проблемы.
Диагностирование исключений
Основные причины возникновения ошибок при пересылке данных или подтверждении работы включают:
* конфликты блокировок;
* "плохие данные", полученные от интерфейса пользователя: арифметическое переполнение, деление на ноль в выражениях, пустые значения в полях, не допускающих пустых значений, несоответствие набора символов и т.д.;
* "хорошие данные", которые нарушают ограничение CHECK или другие проверки;
* нарушения первичного или внешнего ключей;