Автоматическая блокировка
Автоматическая блокировка
В Visual FoxPro может осуществляться автоматическая или ручная блокировка данных. При использовании определенных команд FoxPro попытается автоматически заблокировать записи или всю таблицу (табл. 20.1).
Блокировка при буферизации
Блокировка при буферизации
В Visual FoxPro вы можете выбрать пессимистический и оптимистический режимы буферизации, которые определяют, как и когда будет осуществляться блокировка данных. В зависимости от типа решаемых задач вы можете выбрать один из типов буферизации данных (табл. 20.3).
Блокировка таблицы
Блокировка таблицы
Для установки блокировки изменений таблицы вы должны использовать функцию flock, которая имеет следующий синтаксис:
FLOCK([рабочаяОбласть] | [псевдонимТаблицы])
Функция блокировки проверяет текущий статус рабочей области или таблицы. Если в результате теста определяется, что таблица не заблокирована, она блокируется, и пользователь может продолжать с ней работать. Функция при этом возвращает логическое значение .т. (Истина) и таблица становится доступной пользователю, выполнившему блокировку, на чтение и запись. Остальным пользователям таблица базы данных доступна только на чтение. Если таблица уже заблокирована другим пользователем, заблокировать таблицу не удается и функция возвращает значение .f. (Ложь). Для блокировки таблицы в текущей области псевдоним можно не указывать.
В приведенном ниже примере для блокировки таблицы customer используется команда flocko. Если таблица успешно заблокирована, команда replace all обновляет все записи в ней. После этого команда unlock снимает блокировку файла. Если файл невозможно заблокировать (такая ситуация возникает, если файл уже заблокирован другим пользователем), появится сообщение об ошибке.
SET EXCLUSIVE OFF
SET REPROCESS TO 0
USE Customer IF FLOCK()
REPLACE ALL cLastName WITH UPPER(cLastName)
UNLOCK
ELSE
WAIT "Файл занят, подождите" WINDOW NOWAIT
ENDIF
Если вы редактируете две или более связанных командой set relation таблиц, вам необходимо блокировать каждую связанную таблицу самостоятельно, так как блокировка одной из связанных таблиц не блокирует связанные с ней таблицы. Возможны ситуации, когда вы изменяете данные только в одной таблице, а другие используются для отображения дополнительной информации и их не требуется блокировать.
Блокировка записей
Блокировка записей
По возможности рекомендуется использовать блокировку отдельных записей, а не таблицы в целом. Заблокированная запись может изменяться только установившим блокировку пользователем, остальные пользователи имеют к ней доступ только на чтение. Результат изменения записи будет виден другим пользователям только после снятия блокировки с записи.
Для блокировки записей используются взаимозаменяемые функции lock и rlock, синтаксис которых отличается только наименованием функции:
RLOCK([ рабочаяОбласть I псевдонимТаблицы]
| [номераЗаписей, рабочаяОбласть
| псевдонимТаблицы])
Для указания таблицы, записи которой вы собираетесь блокировать, можно использовать номер рабочей области или псевдоним таблицы. Если не указаны ни рабочая область, ни псевдоним, функция lock будет блокировать текущую запись таблицы, открытой в рабочей области.
Для блокировки группы записей предварительно выполните команду set multilocks on и с помощью аргумента номераЗаписей укажите номера блокируемых записей. Номера записей задаются в символьном виде и разделяются запятыми. Например, для блокировки третьей и пятой записи таблицы необходимо указать "3 , 5".
Замечание
Замечание
Для определения номеров записей используйте функцию recno ().
При успешной блокировке возвращается значение .т. (Истина) и заблокированные записи становятся доступными на чтение и запись пользователю, установившему блокировку. Остальные пользователи могут только просматривать заблокированные записи. При блокировке группы записей функция возвращает значение .т. только в том случае, если удалось заблокировать все указанные записи. Тем не менее записи, которые удалось блокировать, останутся заблокированными.
Если запись или таблица уже заблокированы другим пользователем, блокировка не будет выполнена и функция возвратит значение .f. (Ложь).
Совет
Совет
Для блокировки группы записей вы можете поочередно устанавливать указатель записи на блокируемую запись и выполнять команду lock.
Для выбора режима блокировки одной или группы записей используется команда set multilocks, которая имеет следующий синтаксис:
SET MULTILOCKS ON | OFF
Опция on разрешает блокировку группы записей, а опция off разрешает блокировку только одной записи.
Замечание
Замечание
Переключение установки multilocks из on в off или из off в on приводит к снятию блокировки всех записей во всех открытых таблицах.
Многопользовательская работа в локальной сети
Глава 20. Многопользовательская работа в локальной сети
Многопользовательская работа в локальной сети Типы блокировок Автоматическая блокировка Полная блокировка таблицы и блокировка изменений Блокировка таблицы Блокировка записей Установка режима повторных попыток блокировки данных Снятие блокировок таблиц и записей Сеансы работы с данными Использование буферов Блокировка при буферизации Обнаружение и устранение конфликтов Использование транзакций
Использование буферов
Использование буферов
Одним из мощных средств организации многопользовательской работы в Visual FoxPro является буферизация данных, которая позволяет лучше использовать локальные ресурсы и снижает нагрузку на сеть. При буферизации все сделанные вами изменения хранятся в оперативной памяти на рабочей станции и не обновляются на файл-сервере, пока вы не выполните соответствующую команду.
В Visual FoxPro используются два типа буферизации: буферизация таблиц и записей. При буферизации записей после завершения редактирования записи (при изменении позиции указателя записи или при вызове функции tableupdate) все изменения записываются в базу данных. При буферизации таблиц измененные данные сохраняются в базе данных только при закрытии таблицы или вызове функции tableupdate ().
Использование транзакций
Использование транзакций
Под транзакцией в системах управления базами данных понимают логическую единицу работы, которая представляет собой последовательность нескольких операций, в процессе выполнения которых сохраняется целостное состояние базы данных. В процессе выполнения транзакции обновляемые данные временно хранятся в памяти или на локальном диске. Действительные изменения совершаются только после завершения транзакции. Ес.ш что-либо препятствует обновлению данных, все изменения отменяются и поэтому ваши данные остаются без изменения.
Для управления транзакциями используется три команды, представленные в табл. 20.7.
Многопользовательская работа в локальной сети
Многопользовательская работа в локальной сети
В однопользовательской системе с данными работает только один человек, и ему нет необходимости думать о разделении доступа к файлам. Однако с появлением пользователей, желающих получить доступ к одним и тем же данным, планирование разделения доступа к базе становится актуальным.
В многопользовательских приложениях необходимо обеспечить доступ к данным тем пользователям, которым он действительно нужен. При разработке сетевых приложений по управлению базами данных необходимо предусмотреть разрешение конфликтов, возникающих при попытке двух и более пользователей одновременно изменить одни и те же данные. Visual FoxPro предлагает несколько вариантов решения этой проблемы, позволяя пользователю использовать перед изменением таблиц или записей автоматические или ручные методы их блокировки. При доступе к записям таблицы блокировка запрещает кому-либо изменять заблокированную область, пока пользователь не завершит свои изменения и не разблокирует эти данные.
Эта глава ознакомит вас с концепциями разделения данных в сетевой среде и организацией интерфейса при совместной работе нескольких пользователей.
Обнаружение и устранение конфликтов
Обнаружение и устранение конфликтов
При совместной работе с базой данных возможны конфликты, когда один или более пользователей пытаются заблокировать уже заблокированную другим пользователем запись. Возможны и взаимоблокировки, когда пользователь заблокировал одну запись или таблицу и пытается заблокировать вторую, которая уже заблокирована вторым пользователем. В то же время второй пользователь пытается заблокировать запись, заблокированную первым пользователем. Система буферизации записей и таблиц FoxPro упрощает разработку многопользовательских приложений и устранение возникающих конфликтов.
При попытке заблокировать уже заблокированную запись FoxPro выдает сообщение об ошибке. Для определения возникновения ошибки вы можете воспользоваться функцией tableupdate(), которая возвращает значение .f. при неудачной попытке сохранения данных. Кроме того, вы можете написать программу обработки ошибок и указать ее в команде on error. Для определения причины, по которой не удалось записать данные в базу данных, вы можете использовать значения кодов ошибок. Для определения кодов ошибок используются функции ERROR ( ) или AERROR ( ) .
При использовании буферизации данных в программе обработки ошибок вы можете определить, какие поля были изменены, каким было исходное значение поля и каким оно стало. Для определения изменения поля используется функция getfldstate (), которая по заданному номеру поля возвращает одно из значений, описанных в табл. 20.6.
Полная блокировка таблицы и блокировка изменений
Полная блокировка таблицы и блокировка изменений
В некоторых случаях, например при изменении структуры данных, вам необходимо осуществить полную блокировку таблицы для получения исключительных прав на нее. В этом случае другим пользователям запрещается чтение, запись и изменение структуры указанной таблицы и они не смогут получить к ней доступ. Вы не можете установить полную блокировку, если эта таблица уже открыта или для нее уже установлена блокировка.
В большинстве случаев вам достаточно ограничить изменение данных таблицы, т. е. установить блокировку изменений, которая запрещает запись, изменение структуры указанной таблицы, наложение блокировки изменений другими пользователями.
Для открытия таблицы в режиме полной блокировки используется команда set exclusive on. После выполнения данной команды все открываемые таблицы будут находиться в режиме полной блокировки. Для снятия режима полной блокировки используйте команду set exclusive off. При этом полная блокировка открытых таблиц будет снята только после их закрытия. Для установки полной блокировки отдельной таблицы может быть использована опция exclusive в команде открытия таблицы use. Если таблица открыта в монопольном режиме, необходимость блокировки таблицы или ее записей отсутствует. После закрытия таблицы блокировка автоматически снимается.
Ниже приведены два примера установки полной блокировки таблицы. В первом примере используются две команды, а во втором — таблица открывается в режиме исключительного использования одной командой:
SET EXLUSIVE ON
USE CUSTOMER
ИЛИ
USE CUSTOMER EXCLUSIVE
Некоторые команды, список которых приведен ниже, могут использоваться только в режиме полной блокировки:
ALTER TABLE; INDEX; INSERT [BLANK]; MODIFY STRUCURE; PACK; REINDEX; ZAP.Если вы попробуете применить одну из этих команд, не открыв таблицу для исключительного использования, FoxPro выдаст предупреждающее сообщение Exclusive Open of File Required.
Открытие сеансов работы на одном компьютере
Рис. 20.1. Открытие сеансов работы на одном компьютере
Выбор сеанса работы
Рис. 20.2. Выбор сеанса работы
Определение значения свойства Buf ferModeOverride курсора
Рис. 20.3. Определение значения свойства Buf ferModeOverride курсора
Определение типа блокировки в диалоговом окне Work Area Properties
Рис. 20.4. Определение типа блокировки в диалоговом окне Work Area Properties
При работе в интерактивном режиме вы можете установить тип блокировки в диалоговом окне Work Area Properies (Свойства рабочего пространства) (рис. 20.4), которое открывается при нажатии кнопки Properties (Свойства) в диалоговом окне Data Session (Данные сеанса).
Сеансы работы с данными
Сеансы работы с данными
В Visual FoxPro для многопользовательской работы вы можете использовать сеансы работы с данными, которые представляют собой среду окружения, связанную с формой или набором форм. С помощью сеансов работы с данными вы можете открывать одну и ту же форму на разных рабочих станциях или даже на одном компьютере (рис. 20.1), при этом каждая из них будет использовать отдельную копию данных.
Для управления сеансом работы с данными предназначено свойство DataSession (Окно данных) формы, которое можно установить равным 1 или 2. Если вы установите свойство DataSession равным 1, любые изменения, выполненные вами в форме, будут отображаться во всех остальных открытых формах. Это обычный режим работы. Для открытия копии среды окружения установите значение 2, при этом изменения в данной форме не будут отображаться в других формах. Количество открытых сеансов ограничивается только доступной оперативной памятью и местом на жестком диске.
Для выбора сеанса работы вы можете выполнить любое из следующих действий:
открыть окно Data Session (Окно данных), используя одноименную команду из меню Windows (Окно), и из раскрывающегося списка Current session (Текущий сеанс) выбрать требуемый сеанс работы (рис. 20.2); выполнить в командном окне команду SET DATASESSION TO номерСеанса.Снятие блокировок таблиц и записей
Снятие блокировок таблиц и записей
В большинстве случаев при переходе от одной записи к другой блокировка снимается. Однако если вы заблокировали запись командами блокировки, ее необходимо разблокировать, чтобы к ней могли получить доступ другие пользователи. В табл. 20.2 описаны команды, используемые для снятия блокировок.
Команды, автоматически блокирующие таблицу или записи
Таблица 20.1. Команды, автоматически блокирующие таблицу или записи
Команда | Что блокируется |
ALTER TABLE | Вся таблица |
APPEND | Вся таблица |
APPEND BLANK | Заголовок таблицы |
APPEND FROM | Вся таблица |
APPEND FROM ARRAY | Заголовок таблицы |
APPEND MEMO | Текущая запись |
BLANK | Текущая запись |
BROWSE | Текущая запись и все записи из одноименных полей в связанных таблицах |
CHANGE | Текущая запись и все записи из одноименных полей в связанных таблицах |
DELETE | Текущая запись |
DELETE NEXT 1 | Текущая запись |
DELETE <n> | Если п больше 1, автоматически блокируется вся таблица |
DELETE RECORD <n> | Автоматически блокирует п записей |
DELETE SQL | Текущая запись |
EDIT | Текущая запись и все записи из одноименных полей в связанных таблицах |
GATHER | Текущая запись |
INSERT | Вся таблица |
INSERT SQL | Заголовок таблицы |
MODIFY MEMO | Когда начинается редактирование записи, автоматически блокирует ее |
READ | Текущая запись |
RECALL | Текущая запись |
RECALL NEXT 1 | Автоматически блокирует указанную запись |
RECALL RECORD <n> | Блокирует п записей |
RECALL <n> | Если п больше 1, автоматически блокируется вся таблица |
REPLACE | Текущая запись |
REPLACE NEXT 1 | Автоматически блокирует указанную запись |
REPLACE RECORD <n> | Блокирует п записей |
SHOW GETS | Текущая запись |
TABLEUPDATE() | Вся таблица |
UPDATE | Вся таблица |
UPDATE SQL | Вся таблица |
Замечание
Замечание
Все команды с автоматической блокировкой снимают ее после выполнения.
Команды снятия блокировки записей и таблиц
Таблица 20.2. Команды снятия блокировки записей и таблиц
Команда | Описание |
CLOSE | Снимает все блокировки записей и таблиц |
CLOSE ALL | Снимает все блокировки записей и таблиц |
END TRANSACTION | Снимает все автоматически установленные блокировки |
QUIT | Снимает все блокировки записей и таблиц |
UNLOCK | Снимает все блокировки записей и таблиц в текущей рабочей области |
UNLOCK ALL | Снимает все блокировки записей и таблиц во всех рабочих областях |
USE | Снимает все блокировки записей и таблицы |
SET MULTILOCKS OFF | Позволяет автоматическое снятие текущей блокировки при создании новой |
FLOCK ( ) | Перед блокировкой файла снимает все блокировки находящихся в нем записей |
TABLEUPDATE() | Прежде чем обновить таблицу, снимает все блокировки |
Наиболее часто для снятия блокировок таблиц и записей используется команда unlock, которая имеет следующий синтаксис:
UNLOCK [RECORD номерЗаписи] [IN < рабочаяОбласть | псевдонимТаблицы >] [ALL]
Команда unlock без параметров сбрасывает блокировку текущей записи или таблицы.
При снятии блокировки таблицы опция record не используется, задается только псевдоним таблицы. Если псевдоним не указан, снимается блокировка с текущей таблицы. Для разблокировки всех открытых таблиц используется опция ALL.
Для снятия блокировки с записи укажите опцию record и номер записи.
Замечание
Замечание
Блокировка записи или таблицы может сниматься только пользователем, установившим данную блокировку. Таблицы, открытые в режиме полной блокировки, с помощью команды unlock разблокировать нельзя.
Типы буферизации данных
Таблица 20.3. Типы буферизации данных
Значение | Описание |
1 | Буферы не используются |
2 | Пессимистичная блокировка записей. Visual FoxPro блокирует запись сразу же после начала редактирования данных и освобождает блокировку только после перехода на следующую запись или при выполнении ФУНКЦИИ TABLEUPDATE ( ) |
3 | Оптимистичная блокировка записей. Позволяет редактировать текущую запись в других сеансах работы и блокирует запись только при переходе на следующую запись или выполнении функции tableupdate () |
4 | Пессимистичная блокировка таблицы. Блокируются все редактируемые записи, но их обновление в базе данных осуществляется только при вызове функции tableupdate () |
5 | Оптимистичная блокировка таблицы. Позволяет редактировать записи в других сеансах работы и блокирует записи только при обновлении записей в базе данных с помощью функции tableupdate () |
При выборе любого типа буферизации данных вы можете отказаться от выполненных изменений с помощью функция tablerevert ().
Для установки типа буферизации вы можете использовать функциюCURSORSETPROP() , свойство BufferMode формы и свойство BufferModeOverride курсора, используемого в среде окружения формы.
Свойство BufferMode формы может принимать одно из значений, описанных в табл. 20.4.
Значения свойства BufferMode
Таблица 20.4. Значения свойства BufferMode
Значение | Описание |
0 | Записи блокируются с момента начала редактирования, и значения полей записываются в базу данных при переходе к следующей записи |
1 | Пессимистичная блокировка записей |
2 | Оптимистичная блокировка записей |
Для определения свойства Buf ferModeOverride откройте окно конструктора формы, выполните команду Data Envirofiment (Среда окружения) из меню View (Вид). Далее в окне Data Environment (Среда окружения) выберите таблицу, нажмите правую кнопку мыши и из контекстного меню выберите команду Properties (Свойства). Откроется окно свойств, в котором выберите свойство BufferModeOverride (рис. 20.3) и установите одно из возможных значений (табл. 20.5).
Значения свойства Buf ferModeOverride
Таблица 20.5. Значения свойства Buf ferModeOverride
Значение | Описание |
0 | Буферы не используются |
1 | Использует тип блокировки, заданный свойством BufferMode формы |
2 | Пессимистичная блокировка записей |
3 | Оптимистичная блокировка записей |
4 | Пессимистичная блокировка таблицы |
5 | Оптимистичная блокировка таблицы |
Функция cursorsetpropo, используемая для определения типа буферизации курсора, имеет следующий синтаксис:
CURSORSETPROP(Bu f £ering, типБуферизации,
псевдонимТаблицы | номерРабочейОбласти])
Для определения текущего типа буферизации воспользуйтесь свойством
BufferModeOverride курсора или функцией CURSORGETPROP().
Значения, возвращаемые функцией getfldstate ()
Таблица 20.6. Значения, возвращаемые функцией getfldstate ()
Значение | Состояние |
1 | Значение поля не изменялось |
2 | Значение поля было изменено или поле было удалено |
3 | Значение поля во вновь добавленной записи не изменялось |
4 | Значение поля во вновь добавленной записи было изменено или поле было удалено |
NULL | Конец таблицы |
Команды, используемые для управления транзакциями
Таблица. 20.7. Команды, используемые для управления транзакциями
Команда | Назначение |
BEGIN TRANSACTION | Инициирует транзакцию |
ROLLBACK | Осуществляет откат, то есть аннулирует все выполненные в течение транзакции действия |
END TRANSACTION | Завершает транзакцию и сохраняет все выполненные действия в базе данных |
В некоторых случаях вам может понадобиться использовать вложенные транзакции, при этом каждая из них должна начинаться командой begin transaction и завершаться командой end transaction. Выполнение команды rollback действует только на транзакцию, внутри которой она выполняется. Команды begin и end transaction могут находиться в разных функциях или процедурах.
Типы блокировок
Типы блокировок
В Visual FoxPro вы можете использовать два типа блокировок: блокировку таблицы и записи. Блокировка таблицы запрещает доступ другим пользователям ко всей таблице, пока вы редактируете одну или несколько записей. Применение блокировки записи не допускает изменения записи кем-либо кроме пользователя, установившего блокировку.
По возможности следует использовать блокировку записи, потому что она запрещает изменение только одной записи, а не всей таблицы. Например, пока вы редактируете запись о покупателе Иванове, кто-нибудь может работать с записью о покупателе Петрове. И вы оба можете совершать изменения, не мешая друг другу и не беспокоясь за действия другого.
Установка режима повторных попыток блокировки данных
Установка режима повторных попыток блокировки данных
Если запись или таблица уже заблокированы, вам не удастся с первого раза установить блокировку. В этом случае вы можете использовать команду set reprocess, которая задает количество дополнительных попыток заблокировать таблицу (или запись) или время, на протяжении которого будут выполняться дополнительные попытки блокировки.
Команда set reprocess имеет следующий синтаксис:
SET REPROCESS TO числоПопыток [SECONDS] | TO AUTOMATIC
Если команда содержит опцию seconds, аргумент числоПопыток задает время в секундах, иначе — количество попыток. Аргумент числоПопыток может принимать целые значения в диапазоне от 1 до 32 000, по умолчанию его значение равно 0.
При использовании опции то automatic, а также если значение аргумента числопопыток равно 0, Visual FoxPro будет пытаться выполнять блокировку записи или таблицы до бесконечности. Во время выполнения попыток блокировки будет выводиться сообщение о том, что идет процесс блокировки. Пользователь может прервать процесс установки блокировки нажатием клавиши <Esc>.
При установке set reprocess to -i Visual FoxPro также будет пытаться выполнять блокировку записи или таблицы до бесконечности. Но в этом случае пользователь не может прервать попытки заблокировать запись или таблицу.
Замечание
Замечание
Успешная блокировка записи или таблицы, уже заблокированной другим пользователем, возможна только после того, как пользователь, установивший блокировку, снимет ее. Поэтому рекомендуется снимать блокировку сразу же после завершения операции, для выполнения которой требовалась блокировка.