База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как работают строки кода с управляемой блокировкой данных?
- В этой теме 1 ответ, 2 участника, последнее обновление 10 минут назад сделано
Odin — Одинэсник.
-
АвторЗаписи
-
-
17 октября 2026 в 17:28 #38854
Объясни эти строки по порядку, для чего они нужны и почему именно так:
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(«РегистрНакопления.ОстаткиНоменклатуры»);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.УстановитьЗначение(«Склад», Склад);
ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных(«Номенклатура»,»Номенклатура»);
Блокировка.Заблокировать(); -
17 октября 2026 в 17:28 #38855
Эти строки устанавливают управляемую транзакционную блокировку остатков по нужному складу и товарам. Разберем последовательно.
1С (Код)1Блокировка = Новый БлокировкаДанных;Создается объект, который будет содержать описание одной или нескольких блокировок.
Сам по себе этот оператор ничего не блокирует. Он только создает коллекцию, в которую дальше добавляется область блокировки.
Обычно в одной блокировке можно описать несколько областей, например:
1С (Код)123456789Блокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ДругойЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.СерииТоваров");В вашем случае нужна только одна область, поэтому создается один элемент блокировки.
—
1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");В объект блокировки добавляется область, соответствующая регистру накопления
ОстаткиНоменклатуры.После выполнения этой строки платформа понимает:
> Блокировка будет установлена на данные регистра накопления
ОстаткиНоменклатуры.Переменная
ЭлементБлокировкипредставляет описание блокировки именно этого регистра.Важно, что строка должна соответствовать имени регистра в конфигураторе:
1С (Код)1"РегистрНакопления.ОстаткиНоменклатуры"Если регистр называется, например,
ТоварныеОстатки, тогда нужно указать:1С (Код)1"РегистрНакопления.ТоварныеОстатки"На этом этапе пока еще не определено:
— какая блокировка устанавливается;
— на какой склад;
— по каким товарам;
— когда она будет установлена.Пока только указано пространство, в котором будет действовать блокировка.
—
1С (Код)12ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;Задается режим блокировки.
Исключительныйозначает, что указанные данные будут заняты текущей транзакцией. Другая управляемая транзакция не сможет получить совместимую блокировку на эти же данные до завершения текущей транзакции.Практически для проведения расходной накладной это означает:
1С (Код)12345678910Текущая транзакция:1. Заблокировала остатки.2. Прочитала остатки.3. Проверила наличие товара.4. Сформировала расход.5. Завершила проведение.Другая транзакция:не сможет одновременно изменить или использовать эти же заблокированные данныедо освобождения блокировки.Это нужно для защиты от ситуации, когда два пользователя одновременно проводят расход одного и того же товара.
Например, на складе есть 10 единиц товара.
Два пользователя одновременно проводят документы:
1С (Код)12Документ 1: расход 7 единицДокумент 2: расход 6 единицБез блокировки может произойти следующая последовательность:
1С (Код)12345Документ 1 прочитал остаток: 10Документ 2 прочитал остаток: 10Документ 1 решил, что 7 единиц хватаетДокумент 2 решил, что 6 единиц хватаетОба документа записали расходВ итоге будет списано 13 единиц при фактическом остатке 10.
При использовании исключительной блокировки одна транзакция блокирует остаток. Вторая транзакция ждет завершения первой, после чего читает уже актуальный остаток.
Почему используется именно исключительный режим:
— документ не только читает остатки;
— документ формирует движения расхода;
— нужно исключить параллельное проведение по тем же товарам;
— проверка остатка и запись расхода должны выполняться согласованно.Для простого чтения данных иногда применяется разделяемая блокировка:
1С (Код)1РежимБлокировкиДанных.РазделяемыйНо для проведения документа расхода обычно применяют исключительную блокировку.
—
1С (Код)1ЭлементБлокировки.УстановитьЗначение("Склад", Склад);Эта строка сужает область блокировки до конкретного склада.
Без нее блокировка могла бы относиться ко всему регистру
ОстаткиНоменклатуры.После установки значения:
1С (Код)1ЭлементБлокировки.УстановитьЗначение("Склад", Склад);платформа блокирует данные, у которых измерение
Складравно значению переменнойСклад.Например, если в документе выбран склад
Основной склад, то логика будет такой:1С (Код)12Блокировать не весь регистр,а остатки только по складу "Основной склад".Если в регистре есть измерения:
1С (Код)12СкладНоменклатурато пока задан только склад, область выглядит примерно так:
1С (Код)12Склад = Основной складНоменклатура = любаяТо есть блокировка пока распространяется на все товары выбранного склада. Следующие строки дополнительно сузят ее по номенклатуре.
Название
"Склад"должно точно совпадать с именем измерения регистра накопления. Если измерение называетсяСкладОрганизация, нужно писать:1С (Код)1234ЭлементБлокировки.УстановитьЗначение("СкладОрганизация",СкладОрганизация);Значение
Складобычно является ссылкой на элемент справочникаСклады.—
1С (Код)1ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;Указывается источник данных, из которого будут взяты значения для ограничения блокировки.
В вашем случае
СписокНоменклатурывероятнее всего является табличной частью документа.Например, табличная часть содержит строки:
| Номенклатура | Количество |
|—|—:|
| Товар А | 5 |
| Товар Б | 3 |
| Товар В | 7 |После установки:
1С (Код)1ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;платформа получает возможность использовать строки этой табличной части для формирования области блокировки.
Но одной этой строки недостаточно. Платформе еще нужно объяснить, какое поле источника соответствует какому измерению регистра. Для этого используется следующая строка:
1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Вместе эти две строки означают:
1С (Код)12Возьми значения номенклатуры из табличной частии используй их для ограничения измерения Номенклатура регистра.Источник данных позволяет заблокировать только товары, которые есть в документе, а не всю номенклатуру склада.
—
1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Здесь задается соответствие между полем регистра и полем источника данных.
Первый параметр:
1С (Код)1"Номенклатура"это поле пространства блокировки, то есть измерение регистра накопления.
Второй параметр:
1С (Код)1"Номенклатура"это поле источника данных, то есть колонка в табличной части
СписокНоменклатуры.Получается соответствие:
1С (Код)12Измерение регистра Поле табличной частиНоменклатура НоменклатураЕсли в табличной части есть товары:
1С (Код)123Товар АТовар БТовар Вто блокировка будет установлена примерно на такие комбинации:
1С (Код)123Склад = выбранный склад, Номенклатура = Товар АСклад = выбранный склад, Номенклатура = Товар БСклад = выбранный склад, Номенклатура = Товар ВОстальные товары на этом складе блокироваться не будут.
Именно поэтому источник данных здесь предпочтительнее, чем блокировка всего регистра или всего склада.
### Если не использовать источник данных
Можно было бы заблокировать весь выбранный склад:
1С (Код)1ЭлементБлокировки.УстановитьЗначение("Склад", Склад);Но тогда блокировка затронула бы все товары этого склада:
1С (Код)1Склад = Основной склад, Номенклатура = любаяЭто избыточно. Два пользователя не смогут одновременно проводить документы даже по разным товарам одного склада.
Например:
1С (Код)12Документ 1 проводит Товар АДокумент 2 проводит Товар БПри блокировке всего склада второй документ будет ждать, хотя товары между собой не пересекаются.
При использовании источника данных блокируются только реально используемые товары.
—
1С (Код)1Блокировка.Заблокировать();Это команда фактической установки блокировки.
До этой строки объект
Блокировкатолько содержит описание:1С (Код)1234Какой регистр блокироватьВ каком режимеКакой складКакие товарыИменно вызов:
1С (Код)1Блокировка.Заблокировать();передает это описание платформе и пытается получить блокировку.
Если нужные данные свободны, блокировка устанавливается сразу.
Если другая транзакция уже удерживает конфликтующую блокировку, выполнение может ожидать ее завершения. После освобождения данных текущая транзакция получит блокировку и продолжит работу.
Блокировка действует до окончания текущей транзакции:
— до успешной фиксации транзакции;
— либо до отмены транзакции при ошибке;
— либо до отката проведения.Она не является постоянной блокировкой данных и не записывается в регистр как отдельная информация.
## Что именно блокируется в вашем коде
Если:
1С (Код)1Склад = Основнойа в табличной части есть:
1С (Код)12Товар АТовар Бто логически блокируются следующие области:
1С (Код)1234567РегистрНакопления.ОстаткиНоменклатурыСклад = ОсновнойНоменклатура = Товар АРегистрНакопления.ОстаткиНоменклатурыСклад = ОсновнойНоменклатура = Товар БДругой склад не блокируется:
1С (Код)1Склад = МагазинДругой товар тоже не блокируется:
1С (Код)12Склад = ОсновнойНоменклатура = Товар ВЕсли другой документ работает с
Товаром В, он, как правило, не будет ждать блокировку документа поТовару А.## Почему блокировку устанавливают до запроса остатков
Правильная последовательность для документа расхода:
1С (Код)1234567891011121314151617181920// Удалить старые движения документаДвижения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();// Установить блокировкуБлокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.УстановитьЗначение("Склад", Склад);ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();// Только после блокировки читать остаткиПочему нельзя сначала прочитать остаток, а потом установить блокировку:
1С (Код)12341. Прочитали остаток 10.2. Другой пользователь списал 8.3. Установили блокировку.4. Первый документ списал еще 7.В таком случае проверка выполнялась по устаревшим данным.
Блокировку нужно получать до чтения остатков, чтобы между проверкой и формированием движения другой документ не изменил эти же остатки.
## Важное условие для работы блокировки
Регистр накопления, документ и транзакция должны работать в управляемом режиме блокировок.
Если объект находится в автоматическом режиме, а код вручную устанавливает управляемую блокировку, может возникнуть ошибка вида:
1С (Код)1Автоматический режим блокировки недопустим в этой транзакцииВ конфигураторе нужно проверить свойство:
1С (Код)1Режим управления блокировкой данныхДля документа, его регистров и используемых объектов должен быть выбран управляемый режим, если конфигурация использует явные управляемые блокировки.
Кроме того, имена должны совпадать с метаданными:
1С (Код)1"Склад"должно быть измерением регистра, а:
1С (Код)1"Номенклатура"должно быть одновременно:
— измерением регистра
ОстаткиНоменклатуры;
— колонкой табличной частиСписокНоменклатуры.Если в регистре измерение называется
Товар, а в табличной части поле называетсяНоменклатура, код должен выглядеть так:1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Товар","Номенклатура");То есть первый параметр относится к регистру, второй к источнику данных.
-
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.