Транзакции в Microsoft Visual FoxPro
« Назад Транзакция – это сохраняемые в оперативной памяти изменения таблиц базы данных. При завершении транзакции (команда END TRANSACTION) изменения переносятся на диск, то есть фиксируются в таблицах, участвующих в транзакции. Если в процессе транзакции обнаружена ошибка, то исходные значения в буфере восстанавливаются командой ROLLBACK. Эта же команда и завершает неудавшуюся транзакцию. Команда BEGIN TRANSACTIONначинает транзакцию. Транзакции поддерживаются для таблиц, входящих в базу данных. Для свободных таблиц и курсоров транзакции станут возможными после успешного употребления функции MAKETRANSACTABLE( ). Если транзакция не состоялась, например из-за ошибки сервера или рабочей станции или из-за прекращении работы приложения до фиксации транзакции, или выполнена команда ROLLBACK, то файлы, охваченные транзакцией, вернутся в свое оригинальное состояние. Число вложений транзакций – 5. При превышении этой цифры будет сгенерирована ошибка. Продолжительность транзакции следует минимизировать или выполнять ее, когда другие пользователи не нуждаются в доступе к таблицам: записи, участвующие в транзакции, недоступны (для модификации и чтения) другим сетевым пользователям до ее завершения. При попытке получить доступ к такой записи пользователь будет наблюдать сообщение "Record not available ... please wait" до тех пор, пока запись не освободится. Все индексные IDX-файлы и независимые CDX-файлы во время транзакции не должны быть открыты. Открытыми могут быть только структурные CDX-файлы. Во время транзакции не поддерживаются следующие команды и функция:
* Если CLOSE ALL выполнить во время транзакции, то все отрытые таблицы закроются, но базы данных останутся открытыми. Выполнение CLOSE DATABASES во время транзакции закрывает все таблицы текущей базы данных, но не саму базу данных. Во время транзакции для таблицы, участвующей в транзакции, нельзя употреблять следующие команды и функции:
Пример 1. Команды BEGIN TRANSACTION и ROLLBACK в таблице с буферизацией. close databases open database d:\HomeLibrary\HomeLibrary.dbc use Authors select Authors && && При использовании буферизации set multilocks on && && Активизируем буферизацию таблицы CursorSetProp('Buffering', 5, 'Authors') && && Изменяем значения поля Author во всех записях таблицы replace all Author with Upper(Author) begin transaction && Фиксируем изменения TableUpdate browse last && Наблюдаем преобразованную таблицу && && Отменяем изменения, выполненные во время транзакции rollBack browse last && Наблюдаем преобразованную таблицу && Восстанавливаем представление данных в буфере TableRevert(.T.) browse last && Наблюдаем исходную таблицу В приведенном коде, поскольку используется буферизация, присутствие END TRANSACTION после ROLLBACK недопустимо. Пример 2. Команды BEGIN TRANSACTION и ROLLBACK при отсутствии буферизации. close databases open database d:\HomeLibrary\HomeLibrary.dbc use Authors select Authors begin transaction && Начинаем транзакцию replace all Author with Upper(Author) browse last && Наблюдаем преобразованную таблицу && Отказываемся от преобразований и завершаем транзакцию rollback browse last && Наблюдаем исходную таблицу Команда END TRANSACTIONзавершает текущую транзакцию и сохраняет все изменения таблиц, их memo-файлов и индексов, выполненные во время транзакции. Если транзакция не является вложенной или если завершается транзакция верхнего уровня, то все изменения записываются на диск. Если транзакция вложенная, то END TRANSACTION передает изменения верхнему уровню, на котором, в принципе, могут быть внесены изменения в данные, модифицированные на более низком уровне транзакции. Если END TRANSACTION генерирует ошибку, например по причине нехватки дискового пространства, изменения, выполненные во время транзакции отменяются и транзакция завершается. Перед вызовом END TRANSACTION должна быть выполнена команда BEGIN TRANSACTION. Если используется буферизация и выполнена команда ROLLBACK, то при последующем обращении к END TRANSACTION генерируется ошибка. Пример 1. Транзакция при отсутствии буферизации. close databases open database d:\HomeLibrary\HomeLibrary.dbc use Authors select Authors && begin transaction && Изменяем значения поля Author во всех записях таблицы replace all Author with Upper(Author) end transaction browse last Пример 2. Транзакция при использовании буферизации. close databases open database d:\HomeLibrary\HomeLibrary.dbc use Authors select Authors set multilocks on && && Активизируем буферизацию таблицы CursorSetProp('Buffering', 5, 'Authors') && && Изменяем значения поля Author во всех записях таблицы replace all Author with Proper(Author) && begin transaction && Фиксируем изменения TableUpdate end transaction browse last Команда ROLLBACKотменяет изменения, выполненные в течение текущей транзакции. Текущая транзакции после выполнения ROLLBACK завершается, поэтому употребление END TRANSACTION недопустимо. Возникнет ошибка, если применить ROLLBACK вне транзакции, то есть перед вызовом ROLLBACK должна быть выполнена команда BEGIN TRANSACTION и не должна быть выполнена команда END TRANSACTION или ROLLBACK. Если транзакция вложенная, то ROLLBACK отменяет изменения на текущем уровне транзакции. Все блокировки записей, установленные во время транзакции, после выполнения ROLLBACK снимаются. Функция TXNLEVEL( )возвращает номер текущего уровня транзакции. Если транзакция не начата, то TXNLEVEL( ) вернет 0. Функция ISTRANSACTABLE([nWorkArea | cAlias])возвращает .T., если свободная таблица или свободный курсор поддерживают транзакции, или .F. – в противном случае. Функция MAKETRANSACTABLE([nWorkArea | cAlias])позволяет свободной таблице или свободному курсору поддерживать транзакции. Возвращает .T., если действие выполнено, или .F. – в противном случае. Если функция выполнена успешно, то со свободной таблицей (курсором) можно употреблять управляющие транзакциями команды BEGIN TRANSACTION, END TRANSACTION и ROLLBACK. Таблица, с которой успешно применена функция MAKETRANSACTABLE( ), может поддерживать транзакции во всех рабочих областях и сессиях данных, в которых таблица открыта. То есть результат функции MAKETRANSACTABLE( ) распространяется на все открытые экземпляры таблиц. Если применяется буферизация записи и имеются несохраненные изменения, то перед переходом в режим поддержки транзакции будет выполнено обновление таблицы (курсора). Если употребляется буферизация таблицы, то использование функции MAKETRANSACTABLE( ) недопустимо. Чтобы отменить режим поддержки транзакций, необходимо закрыть свободную таблицу (курсор) во всех сессиях данных. Пример: select test if not Istransactable( ) then Maketransactable( ) endif if Istransactable( ) then begin transaction endif && replace SomeField with 200 && if Istransactable( ) then end transaction endif |