Если вы предоставляете совместный доступ к файлам, то вы должны управлять доступам к данным с помощью блокировки таблиц или записей. Блокировки, в отличие от разрешений по доступу, могут предоставить как краткосрочное, так и долговременное управление доступам к данным. Visual FoxPro предоставляет как ручную, так и автоматическую блокировку данных.

Выбор между блокировкой таблицы или записи

Блокировка записи, вне зависимости - ручная она или автоматическая, предотвращает запись изменений одним пользователем в физическую запись таблицы, если запись уже заблокирована другим пользователем. Блокировка таблицы предотвращает внесение изменений в таблицу другими пользователями, но разрешает чтение данных из полной таблицы. Так как блокировка таблицы запрещает другим пользователя обновлять записи в таблице, то она должна использоваться осторожно.

Выбор между ручной блокировкой или автоматической

В дополнение к выбору между блокировкой таблицы или блокировкой записи, вы, кроме того, можете выбрать между ручной и автоматической блокировкой. Множество команд Visual FoxPro автоматически пытается заблокировать запись или таблицу до их исполнения. Если таблицу или запись удалось заблокировать, то команда исполняется, после чего блокировка снимается.

Команды, которые автоматически блокируют записи или таблицы
Команда Что блокирует

ALTER TABLE

Полную таблицу

APPEND

Заголовок таблицы

APPEND BLANK

Заголовок таблицы

APPEND FROM

Заголовок таблицы

APPEND FROM ARRAY

Заголовок таблицы

APPEND MEMO

Текущую запись

BLANK

Текущую запись

BROWSE, CHANGE и EDIT

Текущую запись и все записи, из полей в связанных таблицах, если началось редактирование поля

CURSORSETPROP( )

Зависит от параметров

DELETE

Текущую запись

DELETE NEXT 1

Текущую запись

DELETE RECORD n

Запись с номером n

DELETE более одной записи

Полную таблицу

DELETE – SQL

Текущую запись

GATHER

Текущую запись

INSERT

Полную таблицу

INSERT - SQL

Заголовок таблицы

MODIFY MEMO

Текущую запись при начале редактирования

READ

Текущую запись и все записи из связанных полей

RECALL

Текущую запись

RECALL NEXT 1

Текущую запись

RECALL RECORD n

Запись с номером n

RECALL более одной записи

Таблицу целиком

REPLACE

Текущую запись и все записи из связанных полей

REPLACE NEXT 1

Текущую запись и все записи из связанных полей

REPLACE RECORD n

Запись с номером n и все записи из связанных полей

REPLACE более одной записи

Таблицу целиком и все записи из связанных полей

SHOW GETS

Текущую запись и все записи, на которые ссылаются связанные поля

TABLEUPDATE( )

В зависимости от  типа буферирования

UPDATE

Таблицу целиком

UPDATE – SQL

Таблицу целиком

Характеристики блокировки записи

Команды, которые пытаются заблокировать запись являются менее ограничивающими, чем команды, которые блокируют таблицу. Когда вы блокируете запись, то прочие пользователи могут продолжить вводить или удалять другие записи. Если запись или таблица уже заблокирована другим пользователем, то попытка блокировки записи или таблицы не будет иметь успеха. Команды, которые пытаются блокировать текущую запись вернут ошибку, "Record is in use by another - Запись занята другим пользомвателем", если запись не может быть заблокирована.

Команды BROWSE, CHANGE, EDIT и MODIFY MEMO не блокируют запись до тех пор, пока не начнете редактировать запись. Если вы редактируете поля записей связанной таблицы, то связанные записи блокируются, если это представляется возможным. Попытка блокировки потерпит неудачу, если текущая запись или любые другие связанные записи уже заблокированы другим пользователем. Если попытка блокировки увенчается успехом, вы можете редактировать запись; блокировка высвобождается, когда вы перемещаетесь к другой записи или активируете другое окно.

Характеристики блокировки заголовка и таблицы

Некоторые команды Visual FoxPro блокируют таблицу целиком, тогда как другие только ее заголовок. Команды, которые блокируют таблицу целиком являются более тяжелыми, чем команды, которые блокируют только заголовок таблицы. Когда вы блокируете заголовок таблицы, другие пользователи не могут вводить записи, но они по-прежнему имеют возможность изменять данные в полях.

Пользователи могут совместно обращаться к таблице, не вызывая конфликта, когда вы выдаете команду APPEND BLANK, но ошибка может наступить в случае, когда другой пользователь также добавляет в таблицу пустую (BLANK) запись. Вы можете отловить ошибку, "File is in use by another - Файл занят другим пользователем" которая возвращается в случае, когда два или более пользователей одновременно исполняют команду APPEND BLANK. Команды, которые блокируют таблицу целиком, возвращают ошибку "File is in use by another - Файл занят другим пользователем", если таблица не может быть заблокирована. Для прекращения попыток блокировки, нажмите клавишу ESC.

Автоматическая блокировка

В приведенном ниже примере, пользователь автоматически блокирует заголовок таблицы добавлением записей из другой таблицы, даже в случае, если customer была открыта в режиме совместного доступа:

 CopyCode imageСкопировать код
SET EXCLUSIVE OFF
USE customer
APPEND FROM oldcust FOR status = "OPEN"

Ручная блокировка

Вы можете вручную блокировать запись или таблицу с помощью одной из приведенных ниже функций блокировки:

Функции LOCK() и RLOCK() могут применяться к заголовку таблицы. Если вы предоставите 0 в качестве записи для LOCK() или RLOCK(), а тесты указывают, что заголовок не заболокирован, то функция блокирует заголовок и возвращает True (.T.).

Если вы блкировали запись или таблицу, убедитесь, что вы сняли блокировку с помощью команды UNLOCK настолько быстро, насколько это возможно, чтобы пользователи имели возможность обратиться к данным таблицы.

Перечисленные функции ручной блокировки производят следующие действия:

  • Проверяют статус блокировки записи или таблицы.

  • Если тесты показывают, что запись разблокирована, блокируется запись или таблица и возвращается True (.T.).

  • Если запись или таблица не могут быть блокированы, пытаются повторно блокировать запись или таблицу, в зависимости от текущей установки SET REPROCESS.

  • Возвращают True (.T.) или False (.F.), указывающие - была ли блокировка успешно.

    NoteСовет

    Если вы желаете проверить статус блокировки записи в вашей сессии без блокирования записи, используйте функции ISRLOCKED() или ISFLOCKED().

Если попытка блокировки записи или таблицы потерпела неудачу, то повторение попыток блокировки будут определять команда SET REPROCESS и ваша процедура обработки ошибок. SET REPROCESS влияет на результат неудачной попытки блокировки. Вы можете управлять числом попыток блокировки или их длительностью с помощью SET REPROCESS.

В приведенном ниже примере открывается для совместного доступа таблица customer и используется FLOCK() для попытки заблокировать таблицу. Есди таблица успешно заблокирована, REPLACE ALL обновляет каждую запись в таблице. UNLOCK высвобождает блокировку файла. Если файл не может быть заблокирован в случае, если он уже заблокирован другим пользователем, то отображается сообщение.

 CopyCode imageСкопировать код
SET EXCLUSIVE OFF
SET REPROCESS TO 0
USE customer    && Таблица открывается для совместного доступа
IF FLOCK()
 REPLACE ALL contact ;    && Замещение данных и разблокировка
  WITH UPPER(contact) 
 UNLOCK   
ELSE  && Вывод сообщения
 WAIT "File in use by another." WINDOW NOWAIT
ENDIF

Разблокировка данных

После того, как вы установили блокировку записи или файла и завершили операции над данными в среде совместного доступа, вы должны снять блокировку настолько быстро, насколько это возможно. Имеется несколько вариантов снятия блокировки. В некоторых случаях, для разблокировки данных достаточно простого перемещения к следующей записи. Прочие ситуации требуют явных команд.

Для разблокировки записи, которая была блокирована автоматически, вам нужно просто переместить указатель записи, даже если у вас была выполнена установка MULTILOCKS ON. Вы должны явно удалить блокировку записи, которая заблокирована вручную; простого перемещения указателя записи в таком случае недостаточно.

В приведенной ниже таблице описываются воздействия команд ручной и автоматической блокировок записи и таблицы.

Команда Действие

UNLOCK

Снимает блокировки записи  и файла в текущей рабочей области.

UNLOCK ALL

Снимает все блокировки во всех рабочих областях текущей сессии.

SET MULTILOCKS OFF

Разрешает автоматическое разблокирование текущей блокировки, чтобы новая блокировка была безопасной.

FLOCK( )

Снимает все блокировки записи файла, перед его блокированием.

CLEAR ALL, CLOSE ALL,USE, QUIT

Снимает все блокировки записи и файла.

END TRANSACTION

Снимает автоматическую блокировку.

TABLEUPDATE( )

Снимает все блокировки после обновления таблицы.

Caution noteПредупреждение

Если запись была автоматически заблокирована в функции, определенной пользователем, а вы переместили указатель за пределы записи и затем снова вернулись к ней, то блокировка будет снят. Используйте табличное буферирование для того, чтобы избежать подобной проблемы.

Смотрите также