Блокировки SAP. Позитивные\Негативные. Пример блокировок

Блокировка - отметка записи в базе данных на время проведения операции(INSERT, UPDATE и т.д.). Служит для предотвращения коллизий при доступе к записи и устанавливается на время операции на уровне БД. SAP для своей системы позволяет создал свою концепцию блокировок, которая позволяет блокировать определенные данные на все время работы транзакции.

Виды блокировок:

Shared Lock (S) - Служит для того, чтобы в процессе показа никто не отредактировал данные. Можно устанавливать несколько блокировок от разных пользователей или транзакций. При этом попытки установить блокировки типов E,X будут отклонены.

Exclusive Locks (E) - Эксклюзивная блокировка устанавливается только для одного LUW. Снимается только пользователем установившим её. Самый распространённый тип блокировки, именно его мы можем увидеть в большинстве транзакций.

Exclusive but not cumulative lock (X) - практически тоже самое, что и тип Е, но может установиться только один раз в пределах транзакции.

Optimistic Lock (O) - Данная блокировка может быть установлена сразу несколькими пользователями. А после переведена в блокировку типа E. При этом остальные блокировки типа О этой записи будут сняты.

Все действия с блокировками происходят при помощи специально сгенерированных ФМ ENQUEUE_E* DENQUEUE_E*
Рассмотрим создание блокировок для таблицы на примере:

заходим в SE11 и вводим желаемое имя. Обратите внимание, что имена начинаются не на Z или Y

Указываем список полей по которым производится блокировка. По умолчанию это ключ таблицы. После того как были указаны поля, необходимо сохранить и активировать объект.

После этого можно перейти к сгенерированным модулям блокировки.

ENQUEUE_E* - установка блокировки
DENQUEUE_E* - снятие блокировки.
Если вы не хотите плодить сущности и вас вполне устраивает блокировка по ключу, можно воспользоваться универсальным модулем блокировки - ENQUEUE_E_TABLE для установки блокировки и DEQUEUE_E_TABLE для снятия

Структура вызова модуля ENQUEUE_E* :

mode_ — Тип блокировки O,X,E,S . В дополнение к этим значениям существуют еще несколько

  • R — перевод ранее установленной оптимистичной блокировки в блокировку на запись E.
  • С — проверка возможности преобразования оптимистичной блокировки в блокировку на запись E.
  • U,V,W — проверка возможности установки блокировки в режимах X,E,S соответственно.

Список параметров — параметры для блокирования. Можно использовать маски, в виде символа @. При этом произойдет блокировка всего диапазона.

X_Параметр — Устанавливаем "Х" для параметра если требуется заблокировать начальное значение.

_SCOPE – может принимать следующие значения:

  • «1» — Блокировка принадлежит диалоговому процессу. Отменяется путем вызова модуля DEQUEUE или выходом из программы.
  • «2» — Блокировка снимается при вызове модуля DEQUEUE или вызовом модуля обновления. В случае если запускается COMMIT WORK и есть отложенные модули обновления (CALL FUNCTION ‘…’ IN UPDATE TASK), блокировка снимается после выполнения модулей обновления V1, на этапе вызова модулей обновления V2 блокировки уже сняты. Если до вызова COMMIT WORK не было запущено модулей обновления, блокировки не будут сняты.
  • «3» — Блокировка является комбинацией "1" и "2". Блокировка снимается при когда ее отменит последний владелец.

_wait – если значение «X», функциональный модуль, в случае если уже стоит блокировка, будет ожидать определённый промежуток времени перед повторным вызовом ФМ. Количество повторений задаётся параметром в профиле (RZ11) — ENQUE/DELAY_MAX. Время, которое будет ожидать система 1 секунда (по умолчанию), параметр ENQUE/DELAY_MAX_REFINE отвечает за то, сколько раз в секунду будет происходить проверка.

_collect – позволяет накапливать блокировку в буфере, а потом установить их все разом пи помощи  ФМ: FLUSH_ENQUEUE. Если хотя бы одну блокировку не удалось осуществить, все остальные тоже не установятся. Буфер можно очистить ФМ: RESET_ENQUEUE

Замечание:
Установка блокировки сама по себе не помешает добавить запись таблицы из другой транзакции. Чтобы все работало как задумано, то и во втором месте необходимо попытаться установить блокировку. По хорошему сделать API для работы с таблицей и все операции проводить через него.

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

Порядок действий при позитивной блокировке:
Фаза 1:
- Проверяем возможность установки блокировки типа O;
- Устанавливаем блокировку;
- Читаем данные;
Фаза 2(изменение данных):
- Проверяем согласованность данных;
- Проверяем возможность перевода блокировки в тип Е и переводим ее в этот тип(При помощи вызова ФМ ENQUEUE_E* c параметром mode_* = R) ;
- Изменение данных;
- Снятие блокировки;

Пример установки позитивной блокировки, с последующим установки блокировки типа 'E'. При этом остальные пользователи не смогут перевести свою блокировку O в тип E.

Посмотреть блокировки можно через транзакцию SM12. Там же можно снять поскольку иногда они не сбрасываются из-за некорректного завершения программы. В особо исключительных случая может потребоваться изменение размера данной таблицы. произвести это можно в транзакции RZ11 enque/table_size.

Добавить комментарий

Ваш адрес email не будет опубликован.