Firebird поддерживает следующие уровни изоляции транзакции:
Firebird осуществляет блокировку уровня строки во всех случаях.
Firebird выполняет оптимистическую блокировку. Ваша транзакция не пытается блокировать запись, пока Вы не выдаете операцию модификации, которая воздействует на ту запись. Это означает, что это возможно, хотя редко, для вашей модификации, чтобы терпеть неудачу, потому что другой клиент блокировал запись, даже если Вы начали вашу транзакцию раньше чем другой клиент.
Firebird использует уникальный версионный двигатель, чтобы достигнуть степени детализации более тонко чем обеспечение традиционной блокировкой уровня строки. Версионный двигатель позволяет любому числу клиентуры читать непротиворечивую копию любой данной записи, даже если в то же самое время другой клиент модифицирует ту же самую строку. Читающие и пишущие одну и туже запись никогда не блокируют друг друга.
Начиная с версии v2.0, Firebird ODBC поддерживает все без исключения типы транзакций, которые может обеспечить сервер, включая блокирование таблиц. Для этого был добавлен SQL синтаксис(GPRE), который выполняется ODBC API функцией SQLExecDirect.
Полная форма запроса:
SET|DECLARE TRANSACTION [LOCAL] [NAME transaction [USING nameUniqueWorkspase]]
[READ WRITE | READ ONLY]
[WAIT | NO WAIT]
[AUTOCOMMIT]
[NO_AUTO_UNDO]
[[ISOLATION LEVEL] {SNAPSHOT [TABLE STABILITY] or REPEATABLE READ
| SERIALIZABLE
| READ COMMITTED [[NO] RECORD_VERSION]}]
[RESERVING 'reserving_clause'];
'reserving_clause' = table [, table :]
[FOR [SHARED | PROTECTED] {READ | WRITE}] [,
Назначение и описание.
DECLARE TRANSACTION... - декларируем описание транзакции, без ее выполнения.
SET TRANSACTION... - ставим транзакцию на выполнение, выключая глобальную
установку SQL_ATTR_AUTOCOMMIT в положение SQL_AUTOCOMMIT_OFF. После
завершения текущей будет работать указанная.
LOCAL - определяет выполнение транзакции в пределах активного оператора(запроса).
NAME transaction - уникальное имя транзакции, по которому формируется.
в глобальном окружении соединений таблица транзакции подготовленных на выполнение.
USING nameUniqueWorkspase - уникальное имя рабочего пространства транзакции,
по которому формируется в глобальном окружении соединений таблица транзакции
подготовленных на выполнение, имея два активных соединения, которые могут иметь
одинаковые названия транзакций, но разные их описания.
DECLARE TRANSACTION ... [NAME transaction [USING nameUniqueWorkspase]]
Эта форма записи предназначена для предварительной подготовки описаний
транзакций, которые сохраняются в глобальном окружении соединений. Это
экономит время и позволяет многократно использовать для любого активного
соединения. Вызов такой транзакции на выполнение выполняется командой:
- для соединения
- для отдельного запроса в пределах одного соединения
SET TRANSACTION ... [NAME transaction [USING nameUniqueWorkspase]]
Эта форма записи отличается от предыдущей тем, что ставит транзакцию
на выполнение, после завершения активной, если такая имеется. Однако
если указано ключевые слова NAME или USING, тогда эта транзакция может
так же многократно вызываться уже только с указанием ее имени.
Примечание. Для возврата в обычный режим работы, необходимо выполнить
переоткрытие соединения.
Так же, добавлено обслуживание SQL запросов COMMIT и ROLBACK, эти
вызовы выполняют ту же работу что и основной вызов SQLEndTran.
Есть программы, которые умеют вызывать SQLExecDirect и не
умеют вызывать SQLEndTran. Для этих программ нужно ставить вызов
Эта возможность позволяет максимально на 16 разных Firebird базах данных
выполнять commit(совершать) транзакции. Например, используя инструкцию
Вы сообщаете Firebird ODBC, что это соединение должно участвовать в схеме "two phase commit transactions". Подключив этой командой несколько соединений и выполняя на любом соединении Commit или Rollback, Вы получите схему "two phase commit transactions". Для исключения соединения из схемы используйте инструкцию:
HSTMT stmtRd; HSTMT stmtWr; SQLAllocHandle( SQL_HANDLE_STMT, connection, &stmtRd ); SQLAllocHandle( SQL_HANDLE_STMT, connection, &stmtWr ); SQLExecDirect( stmtRd, (UCHAR*) "SET TRANSACTION LOCAL\n" "READ ONLY\n" "ISOLATION LEVEL\n" "READ COMMITTED NO RECORD_VERSION WAIT\n", SQL_NTS ); SQLExecDirect( stmtWr, (UCHAR*) "SET TRANSACTION LOCAL\n" "READ WRITE\n" "ISOLATION LEVEL\n" "READ COMMITTED NO RECORD_VERSION WAIT\n", SQL_NTS ); SQLExecDirect( stmtRd,(UCHAR*) "SELECT CURRENCY FROM COUNTRY" " WHERE country = 'Canada'" " FOR UPDATE OF CURRENCY", SQL_NTS ); SQLFetch( stmtRd ); SQLPrepare( stmtWr, (UCHAR*) "update COUNTRY\n" "set CURRENCY = 'CndDlr'\n" "where COUNTRY = 'Canada'\n", SQL_NTS ); SQLExecute( stmtWr ); SQLExecDirect( stmtWr, (UCHAR*)"COMMIT", SQL_NTS );
Для более подробного ознакомления с этими и другими возможностями пожалуйста, рассмотрите примеры.