Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
В редких случаях более двух транзакций может быть включено во взаимную блокировку при борьбе за перекрывающиеся наборы. Иногда это называется тупиковой ситуацией (программистский жаргон - deadly embrace, смертельные объятия). Сканирование блокировок выберет одну транзакцию (нашу транзакцию), ситуация будет обработана в клиентском обработчике исключений, как в предыдущем примере. При этом даже если клиент выполнит откат нашей транзакции, те другие транзакции все еще останутся заблокированными.
Клиент может запустить новую транзакцию
Короче говоря, важно в первую очередь исключить контексты транзакций, которые могут привести к тупиковой ситуации. В качестве дополнительной защиты обработчики исключений должны быть способны быстро обрабатывать блокировки и обеспечивать, чтобы проблемные транзакции завершались чисто и без задержек.
Далее мы рассмотрим транзакции с точки зрения разработчика клиентских приложений. Темы в этой главе являются нейтральными к включающим языкам. Тем не менее все современные средства разработки приложений и драйверы для Firebird используют один и тот же API в той или иной форме, что хорошо для одного, хорошо и для другого.
ГЛАВА 27. Программирование с транзакциями.
Транзакция является начальной точкой для всех взаимодействий клиентского приложения с сервером. В этой главе мы с точки зрения различных интерфейсов клиента рассмотрим запуск, управление и завершение транзакций.
Многие языки и средства разработки имеют интерфейс с Firebird. Подробное описание управления транзакциями Firebird в каждом из них находится за пределами данной книги.
Язык для транзакций
Важно обратиться к средствам реализации транзакций в Firebird. До сих пор некоторые связанные с транзакциями особенности вовсе не реализованы в динамическом SQL, а только через API. Среди небольшого количества связанных с транзакциями операторов SQL и доступных в подмножестве DSQL только COMMIT и ROLLBACK доступны в каждом интерфейсе. В книге осознанно выбран нейтральный подход к языкам средств разработки. Основной акцент делается на динамический SQL, используемый в большинстве существующих средств разработки клиентских приложений. В главе представлены некоторые проблемы, одинаково актуальные и для автора, и для читателя.
Хотя эта глава не описывает ESQL [98] или API [99] , следующие разделы будут рассказывать о них в более или менее общем виде для получения некоторого понимания того, что передается через интерфейс, когда клиенты "беседуют" с серверами о транзакциях.
ESQL
Надмножество операторов SQL и подобных SQL операторов, используемых в прежние времена, даже до публикации API и подмножества DSQL, представляет синтаксис стандарта SET TRANSACTION для конфигурирования и старта транзакций. В некоторых формах он доступен в DSQL и может быть использован в утилите isql. Это удобное средство общей проверки того, как API передает эквивалентную информацию [100] .
98
Для
99
То же, "API Guide" (Руководство по API). APlGuide.pdf.
100
SET TRANSACTION, как COMMIT и ROLLBACK, не является оператором, выполняемым на сервере. Будучи оператором Embedded SQL он преобразуется утилитой gpre (или isql) в вызовы Firebird API (isc_start_transaction...).
– Прим. науч. ред.
API
API предоставляет гибкий интерфейс множества сложных функций программистам С и C++ для создания клиентских приложений с наиболее тонким уровнем связи и соединения. Группа функций API реализует эквивалентные операторы SQL, относящиеся к транзакциям, например isc_start_transaction для оператора START TRANSACTION и isc_commit_transaction для оператора COMMIT.
Заголовочный файл API, ibase.h, объявляет прототипы функций, определения типов для каждой структуры, определения параметров и макросы, которые используются в функциях. Он поставляется в каталоге Firebird /include.
Для некоторых объектно-ориентированных сред разработки, таких как Object Pascal, Borland C++ Builder, Java, PHP, Python и DBI::Perl классы и компоненты полностью инкапсулируют вызовы API Firebird, относящиеся к транзакциям. Пользовательские драйверы для интерфейсов соединения со стандартными базами данных SQL - в особенности ODBC, JDBC и .NET- похожим образом представляют API [101] .
Запуск транзакции
101
Для большинства этих реализаций была выполнена трансляция заголовочного файла С Firebird в соответствующий язык высокого уровня для предоставления средств API Firebird (или InterBase) для этого языка. Если вы планируете разрабатывать программы с использованием API, хорошим решением будет поиск в Интернете существующих трансляций заголовочного файла.
SQL
Оператор SQL для запуска транзакции имеет следующий синтаксис:
SET TRANSACTION [NAME <имя-транзакции>]
[READ WRITE | READ ONLY] /* режим доступа */
[WAIT | NO WAIT] /* режим разрешения блокировок */
[ISOLATION LEVEL] /* уровень изоляции */
{SNAPSHOT [TABLE STABILITY] | READ COMMITTED [[NO] RECORD VERSION]}
[RESERVING <предложение-резервирования>
| USING <дескриптор-базы-данных> [,дескриптор-базы-данных...]];
Финальное предложение RESERVING задает необязательное резервирование таблиц, обсуждавшееся в предыдущей главе. Его синтаксис представляется в виде:
<предложение-резервирования> : := <таблица> [, <та&лица> ...] [FOR [SHARED | PROTECTED] {READ | WRITE}]
[, <предложение-резервирования> [, <предложение-резервирования> ...]]
! ! !
ПРИМЕЧАНИЕ. Необязательное имя транзакции - объявляемое в приложении и указываемое в предложении SET TRANSACTION - недоступно нигде, кроме ESQL.