Имя: Пароль:
1C
1С v8
Замещение периода в независимом регистре: кто реально ловил lost update?
0 Nedomolkov_
Ivan
 
04.08.26
14:14
Регламентный расчёт пишет в независимый регистр сведений (периодичность День), порядка 8 400 строк за прогон. Сделано в лоб: МенеджерЗаписи.Записать() в цикле.

Переписал на набор записей: отбор по периоду, Прочитать(), заместить строки, Записать(Истина) одним вызовом. На тех же данных разница в десятки раз.

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

Моя позиция: для регламента, который по замыслу крутится раз в сутки одним фоновым заданием, это перестраховка. Защита от двойного запуска - отдельная задача (управляемая блокировка, проверка активных заданий), и решать её надо там, а не отказом от пакетной записи в принципе.

Интересно, что видели в бою:

1. Кто-нибудь реально ловил потерю чужих строк на замещении периода? Какая была схема?
2. Если пишете пакетно - блокировку берёте на период целиком или на период+измерение?

Повод для вопроса: гонял эту задачу через несколько ИИ-агентов. Двое переписали на пакетную запись, третий отказался ровно с аргументом про lost update. Спор показался осмысленным независимо от того, кто его начал.
1 Dmitrii
 
гуру
04.08.26
14:26
Наверное при пакетной записи правильным было бы устанавливать блокировку. На период или на период+измерение - зависит уже от конкретики.

>> ...это перестраховка

Возможно.
Но если какая-то фигня может произойти, она обязательно произойдёт. Рано или поздно.
Если есть способ её избежать, лучше её избежать.
2 Homer
 
04.08.26
14:32
Переделать на 2 независимых регистра.
3 zenik
 
04.08.26
14:38
Если у пользователя что то медленно делается - он нервничает. Вот тут стоит оптимизировать и ловить секунды.
А фоновое - лучше пусть делает упор на качество, нежели скорость.
4 Ненавижу 1С
 
гуру
04.08.26
15:00
А почему параллельный процесс что-то пишет и что-то другое? Короче нужны подробности
5 Nedomolkov_
Ivan
 
04.08.26
15:50
(1) Согласен, и это похоже единственный честный ответ. Управляемая блокировка на регистр с отбором по периоду стоит копейки, а окно закрывает целиком. Перестраховка — это когда защита дороже риска, тут не тот случай.

(4) Двух регламентов там нет. Окно открывают ручной пересчёт того же периода и повторный запуск задания поверх подвисшего. Сам потерю строк на этом не ловил — потому и спрашиваю, ловил ли кто-то в бою.

(2) Архитектурно верно, но тогда каждый, кто эти данные читает, обязан складывать два регистра. Цена выше, чем у одной блокировки.

(3) Скорость тут не ради спорта: построчно 8 400 строк перестали укладываться в окно. От набора записей страдает не качество, а атомарность — её блокировка и чинит.
6 Garykom
 
гуру
04.08.26
15:52
1. https://habr.com/ru/companies/otus/articles/1005778/
2. Распараллеливание одного регламента на кучу (до 50 штук) фоновых
По какому или каким разрезам делить это уже на усмотрение, и там же по ним блокировать
7 YFedor
 
04.08.26
16:19
(0) Набор при чтении же не блокирует При записи набора - весь набор с отбором и перезапишется, в момент транзакции записи заблокируется по отбору. Т.е. пока ты в набор добавляешь записи, кто-то сможет записать такие же записи параллельно, но они затрутся при записи твоего набора.

С блокировками не работал, но может быть есть возможность после чтения набора заблокировать регистр по отбору, а перед записью блокировку снять
8 Nedomolkov_
Ivan
 
04.08.26
16:22
(7) Механика ровно такая, да: чтение набора блокировку не ставит, а при Записать(Истина) платформа берёт её уже внутри собственной транзакции. Окно между чтением и записью так и остаётся открытым, поэтому чужие строки затираются молча, без единой ошибки в журнале.

Снять блокировку перед записью не выйдет: управляемая живёт до конца транзакции, раньше её не отпустить. Да и снимать нечего — окно открывается ровно в этот момент. Схема обратная: НачатьТранзакцию, БлокировкаДанных по регистру с отбором по периоду в исключительном режиме, Прочитать, заместить, Записать, ЗафиксироватьТранзакцию. Блокировка держится до фиксации, параллельный сеанс ждёт.

(6) Разбиение на пачку фоновых снимает время, но lost update не снимает, а размножает: если делить по разрезу, а замещать набором с отбором только по периоду, задания начнут затирать друг друга на одном и том же дне. Значит отбор и блокировка обязаны идти по паре период плюс разрез, оба сразу.
9 timurhv
 
04.08.26
16:39
10 timurhv
 
04.08.26
16:45
+ (9) блокировки накладывать по измерениям при записи пакета, весь период можно не блокировать.

В итоге таблица с пакетной записью по ссылкам выше:
04.08.2026 - Измерение1 - Ресурс
04.08.2026 - Измерение2 - Ресурс

не заблокирует запись пользователем:
04.08.2026 - Измерение3 - Ресурс
11 Сергиус
 
04.08.26
16:51
(0)Если период день, то пишите ночью, когда пользователи не работают(обычно, хотя всякое бывает)..
12 Garykom
 
гуру
04.08.26
17:13
(8)
отбор и блокировка обязаны идти по паре период плюс разрез, оба сразу
угу
13 Nedomolkov_
Ivan
 
04.08.26
17:22
(10) Согласен, но с оговоркой: блокировка не должна быть уже отбора, которым замещаешь. Если набор идёт с отбором только по периоду, он затрёт и Измерение3 — как бы аккуратно ни были заблокированы Измерение1 и Измерение2. Работает только пара целиком: отбор набора и блокировка по одному и тому же ключу. Тогда да, соседнее измерение пишется параллельно и никому не мешает, это лучше, чем лочить день целиком.

(9) За ссылки спасибо, вторая по делу. Боевого опыта с 8.3.26 у меня нет: базы, которые я вижу, живут на платформах постарше, так что режим замещения пока читаю как обещание, а не как инструмент.

(11) Так оно и крутится ночью. Окно открывают не пользователи, а ручной пересчёт того же дня и повторный запуск задания поверх подвисшего — и случается это как раз ночью, когда никто не смотрит.