LockStorage

From SunFlurry wiki
Jump to: navigation, search
  LockStorage (Блокировка накопителей)
Объект:Функции общего назначения
Статус разработки: Реализована
Тип:Функция
Обращение к БД:Сервер
Исключения:Невозможно превратить в строку, неверный накопитель, ошибка блокировки
Визуальность:Нет

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

  1. Блокировка требуемого накопителя (или нескольких) с помощью функции LockStorage. Часто информация, попадающая в накопители, непосредственно связана с текущей информацией в них. К примеру, при списывании остатков товара на складе, перед списанием необходимо убедиться, что сальдо по остатку не станет отрицательным, и, если это такой случай, отказать в записи в накопитель. Однако, если не заблокировать накопитель до момента проверки текущего сальдо, может получиться ситуация, когда проверка покажет определенное значение, а сразу после нее, другой пользователь осуществит списание некоторого количества этого товара, программа, руководствуясь устаревшими данными, разрешит списание и на складе может остаться отрицательное количество товара, что изначально предполагалось не допустить. Блокировка до начала проверки остатков не позволяет другим пользователям производить изменения в накопителе до его разблокирования, тем самым устраняя вероятность такой ситуации. Также можно использовать функцию ClearStorages вместо LockStorage, последняя не только производит блокировку накопителя(ей), но и очищает их движения для выбранного документа, что, возможно, предпочтительнее для выполнения проверки. Функцию ClearStorages необходимо всегда выполнять внутри транзакции.
  2. Выполнение требуемых проверок по корректности записываемой информации.
  3. Создание и заполнение таблицы для записи в накопитель (InitStorageTab и пр.)
  4. Инициирование режима транзакции BeginTransaction
  5. Сохранение информации в накопитель (SaveStorage). Данная функция производит автоматическое блокирование накопителя, если в данный момент работает режим транзакции, однако, по соображениям, данным выше, блокировку правильнее производить заранее.
  6. Фиксирование транзакции с помощью функции CommitTransaction. Данная функция произведет автоматическую разблокировку накопителей, поэтому, нет необходимости вызывать UnlockStorage.


Ниже дата информация по разным типам блокировки системы:

Тип блокировки Разрешено вложение Примеры функций Описание
Блокировка объектов на уровне системы Да (объект будет разблокирован после такого же количества вызовов UnlockObject, сколько было вызовов LockObject) LockObject, UnlockObject, LockCount Производится блокировка доступа к объекту из других потоков. Используется, когда для сохранения непротиворечивого состояния объекта необходимо сделать более одного изменения, к примеру, изменить в строке таблицы, которая используется в других потоках, сразу несколько значений. Если достаточно изменить только одно значение, не имеет смысла использовать подобную блокировку, так как система самостоятельно блокирует сложные объекты при их чтении или записи. Требуется конструкция Try ... Finally, чтобы снять блокировку гарантированно.
Блокировка визуальных элементов форм Нет (Unlock всегда разблокирует, вне зависимости от количества вызовов Lock) Tab.Lock, Tab.Unlock, List.Lock, List.Unlock, Tree.Lock, Tree.Unlock, Table.Lock, Table.Unlock, Picture.Lock, Picture.Unlock Производится блокировка трансляции изменений на экран, сделанных в объекте в программе. Данная блокировка используется для ускорения работы с объектами, которые уже выведены на экран. Если электронная таблица еще не выведена на экран, нет никакого смысла проводить такую блокировку, так как она не ускорит работы с таблицей. Требуется конструкция Try ... Finally, чтобы снять блокировку гарантированно.
Блокировка объектов базы данных N/A DB.Lock, DB.Unlock, MassLockWithWait, MassUnlock Производится блокировка объекта базы данных на сервере. Клиент выполняет такую блокировку автоматически, когда пользователь открывает элемент справочника или документ визуально. Программная блокировка необходима, если нужно заблокировать группу объектов до их изменения, либо необходимо произвести несколько последовательных изменений в одном объекте. После блокировки объекта, если это не новый объект, рекомендуется загрузить его содержимое заново с помощью DB.Reload, чтобы избежать записи устаревшей информации и, тем самым, утери более свежих изменений. Разблокировка происходит при удалении объекта из системы, закрытии визуально закрытого объекта, либо вызове функции разблокировки.
Блокировка накопителей и определенных видов объектов. N/A LockStorage, UnlockStorage, LockDBPath, UnlockDBPath Производится блокировка накопителя или другого объекта для всех пользователей системы. Блокировка используется перед критической проверкой содержания накопителя, для того, чтобы убедиться, что после проверки перед записью накопитель не был изменен. Такая блокировка обычно сопровождается транзакцией BeginTransaction, даже без вызова LockStorage, она инициируется автоматически при вызове некоторых функций, типа ClearStorages, SaveStorage. Разблокировка происходит автоматически при окончании транзакции, ошибке или окончании выполнения программного модуля. Более подробную информацию см. в статье LockStorage.
Блокировка серверных семафоров N/A DBLockStringMutex, DBUnlockStringMutex, MassLockWithWait, MassUnlock Производится блокировка именованных семафоров на сервере. Блокировка необходима, если нужно заблокировать доступ к процессу, не связанному с элементами базы данных (например, к файловому каталогу на сервере). Требуется конструкция Try ... Finally, чтобы снять блокировку гарантированно.
Транзакции базы данных Да (фактически транзакция будет зафиксирована после такого же количества CommitTransaction, сколько было вызовов BeginTransaction, однако, RollbackTransaction отменяет все уровни транзакции). BeginTransaction, CommitTransaction, RollbackTransaction Блокировка изменения любых таблиц на сервере базы данных для других клиентов, после того, как они были изменены текущим внутри транзакции, называется блокировкой транзакции. Транзакция может окончится принятием изменений, сделанных внутри нее, либо отказом от них, после чего, таблицы становятся доступными для записи других клиентов. Транзакция может происходить очень незаметно для других клиентов, а может замедлять скорость работы всех пользователей системы, в зависимости от типа объекта, для которого она происходит. По умолчанию работа клиента на сервере базы данных идет вне транзакции, однако, при записи изменений в объекты, сервер базы данных может создавать кратковременную транзакцию (хотя практически, это не делается, так как сервер разграничивает доступ клиентов с помощью внутреннего механизма блокировок). Транзакция, однако, создается сервером автоматически при обработке документов, причем, при этом происходит блокировка не отдельных объектов, а видов объектов (накопителей), поэтому, корректная оптимизация кода обработки документов очень важна. Программа использует транзакции, когда результат записи изменений множества связанных объектов нельзя предсказать заранее. Требуется конструкция Try ... Finally, чтобы окончить транзакцию гарантированно, иначе транзакция будет отменена системой автоматически после окончания выполнения кода.
Блокировка системных семафоров N/A Mutex.CreateMutex Производится блокировка системного семафора, что позволяет исключить доступ к одному и тому же имени для двух или более запущенных клиентов на одной и той же машине, либо позволяет производить простое разграничение доступа между клиентом и другими приложениями. Разблокировка происходит при удалении объекта из системы.

Синтаксис

LockStorage(<Наименование накопителя (STRING)>)

Аргументы

  • <Наименование накопителя (STRING)> - Наименование накопителя, который необходимо заблокировать


Примеры

//Фрагмент иллюстрирует описанную выше последовательность действий по записи в накопитель
//аДок -- текущий документ, в накопитель которого необходимо выполнить запись
LockStorage("Остатки");
ФлБлокировка:=1;
ФлТранзакция:=0;
Try
  флПроверкаУдачна:=1;
  //Далее следуют проверки, изеняющие флПроверкаУдачна
  ...
  If not флПроверкаУдачна Then
    Exit;
  EndIf;

  aTab:=аДок.InitStorageTab("Остатки");
  //Заполнение таблицы aTab
  ...

  //Сохранение изменений
  BeginTransaction();
  ФлТранзакция:=1;
  аДок.SaveStorage("Остатки",aTab,аДок.DocDate);

  //Фиксирование транзакции
  ФлТранзакция:=0;
  CommitTransaction();
  ФлБлокировка:=0;

Finally
  If ФлТранзакция Then
    RollbackTransaction();
  ElseIf ФлБлокировка Then
    UnlockStorage("Остатки");
  EndIf;
EndTry