#std661¶
Блокирующее чтение остатков в начале транзакции¶
1.1.¶
В ряде задач нужно выполнять блокирующее чтение итогов. Типовой случай - контроль остатков при проведении документа.
Если после проведения остатки становятся отрицательными, транзакцию нужно отменять. Проводить такой документ нельзя.
1.2.¶
Чтение остатков в этом сценарии должно быть блокирующим. Нужно запретить двум пользователям одновременно читать один и тот же остаток за период, счет и значения измерений.
Если чтение неблокирующее, два пользователя могут одновременно прочитать один и тот же остаток и независимо принять решение о списании.
Пример: оба пользователя видят 10 единиц остатка.
Первый списывает 8, второй списывает 6.
Итоговый остаток становится -4, что недопустимо для прикладной логики.
2.¶
Обычно контроль остатков делают запросом в модуле набора записей перед записью набора. У такого подхода есть две проблемы:
- разработчик, как правило, не управляет порядком записи движений в разные регистры (платформа пишет их автоматически);
- в части сценариев контроль не нужен, потому что движения заведомо не могут дать отрицательные остатки.
Если регистр с контролем записывается в начале транзакции, блокировка держится долго и мешает другим пользователям, пока пишутся остальные регистры.
Чтобы минимизировать влияние блокирующего чтения на производительность:
- заранее анализируйте, какие остатки нужно контролировать и в каких случаях;
- учитывайте сценарии, где контроль не нужен:
- приходный документ может только увеличить остатки;
- при перепроведении документ может списывать не больше, чем списал при первом проведении;
- в начале транзакции (например, в
ОбработкаПроведения) явно записывайте движения по регистрам, где контроль не нужен; - всегда используйте одинаковый порядок записи регистров (например, алфавитный);
- для этих наборов записей ставьте
БлокироватьДляИзменения = Ложь; - убедитесь, что у всех записываемых регистров накопления и бухгалтерии включен режим разделения итогов;
- выполните остальную логику транзакции;
- в самом конце транзакции явно запишите движения по регистрам, где контроль нужен;
- для наборов записей этих регистров ставьте
БлокироватьДляИзменения = Истина(это снижает риск взаимоблокировок); - после записи выполняйте запросы контроля остатков по отрицательным остаткам для нужного набора измерений;
- если отрицательные остатки найдены, отменяйте транзакцию; если запрос пустой, фиксируйте.
Явную управляемую блокировку (ДЛЯ ИЗМЕНЕНИЯ в автоматическом режиме)
в этом месте обычно не используют, потому что нужные остатки уже заблокированы записью на предыдущем шаге.
Пример¶
В процедуре ПередЗаписью модуля набора записей регистра бухгалтерии Хозрасчетный
выполняется запрос:
Пример запроса
Такой запрос читает и блокирует остатки по условию для всех пользовательских подключений. Ресурсы, созданные разделением итогов, фактически объединяются в один. В результате параллельность становится такой же, как если бы разделение итогов было отключено.
Чтобы снизить влияние этой блокировки, переносите проверку как можно ближе к концу транзакции.
Например, в модуль документа, в ПриПроведении, после явной записи всех движений по всем регистрам.