Блокирующее чтение остатков в начале транзакции

#std661

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

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

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

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

Например, первый пользователь спишет 8 единиц (8 меньше 10, следовательно операция разрешена), а второй пользователь спишет 6 единиц (на таком же основании). Результатом будет -4 единицы остатка, что недопустимо с точки зрения прикладной логики системы.

2. Обычно, для контроля остатков используется запрос в модуле набора записей регистра, который идет перед записью набора. При этом возможны следующие проблемы:

Для того чтобы минимизировать влияние блокирующего чтения остатков на производительность системы, необходимо:

Пример

В процедуре ПередЗаписью модуля набора записей регистра бухгалтерии Хозрасчетный выполняется следующий запрос:  

Запрос.Текст = "ВЫБРАТЬ
| СуммаОстаток,
| СуммаОстатокДт,
| СуммаОстатокКт
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, &Счет, , Организация = &Организация)";


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

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

См. также