Как работают строки кода с управляемой блокировкой данных?

База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как работают строки кода с управляемой блокировкой данных?

Просмотр 1 ветки ответов
  • Автор
    Записи
    • #38854
      Фото аватараOdineski
      Участник

        Объясни эти строки по порядку, для чего они нужны и почему именно так:
        Блокировка = Новый БлокировкаДанных;
        ЭлементБлокировки = Блокировка.Добавить(«РегистрНакопления.ОстаткиНоменклатуры»);
        ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
        ЭлементБлокировки.УстановитьЗначение(«Склад», Склад);
        ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
        ЭлементБлокировки.ИспользоватьИзИсточникаДанных(«Номенклатура»,»Номенклатура»);
        Блокировка.Заблокировать();

      • #38855
        bot_avaOdin — Одинэсник
        Участник

          Эти строки устанавливают управляемую транзакционную блокировку остатков по нужному складу и товарам. Разберем последовательно.

          Создается объект, который будет содержать описание одной или нескольких блокировок.

          Сам по себе этот оператор ничего не блокирует. Он только создает коллекцию, в которую дальше добавляется область блокировки.

          Обычно в одной блокировке можно описать несколько областей, например:

          В вашем случае нужна только одна область, поэтому создается один элемент блокировки.

          —

          В объект блокировки добавляется область, соответствующая регистру накопления ОстаткиНоменклатуры.

          После выполнения этой строки платформа понимает:

          > Блокировка будет установлена на данные регистра накопления ОстаткиНоменклатуры.

          Переменная ЭлементБлокировки представляет описание блокировки именно этого регистра.

          Важно, что строка должна соответствовать имени регистра в конфигураторе:

          Если регистр называется, например, ТоварныеОстатки, тогда нужно указать:

          На этом этапе пока еще не определено:

          — какая блокировка устанавливается;
          — на какой склад;
          — по каким товарам;
          — когда она будет установлена.

          Пока только указано пространство, в котором будет действовать блокировка.

          —

          Задается режим блокировки.

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

          Практически для проведения расходной накладной это означает:

          Это нужно для защиты от ситуации, когда два пользователя одновременно проводят расход одного и того же товара.

          Например, на складе есть 10 единиц товара.

          Два пользователя одновременно проводят документы:

          Без блокировки может произойти следующая последовательность:

          В итоге будет списано 13 единиц при фактическом остатке 10.

          При использовании исключительной блокировки одна транзакция блокирует остаток. Вторая транзакция ждет завершения первой, после чего читает уже актуальный остаток.

          Почему используется именно исключительный режим:

          — документ не только читает остатки;
          — документ формирует движения расхода;
          — нужно исключить параллельное проведение по тем же товарам;
          — проверка остатка и запись расхода должны выполняться согласованно.

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

          Но для проведения документа расхода обычно применяют исключительную блокировку.

          —

          Эта строка сужает область блокировки до конкретного склада.

          Без нее блокировка могла бы относиться ко всему регистру ОстаткиНоменклатуры.

          После установки значения:

          платформа блокирует данные, у которых измерение Склад равно значению переменной Склад.

          Например, если в документе выбран склад Основной склад, то логика будет такой:

          Если в регистре есть измерения:

          то пока задан только склад, область выглядит примерно так:

          То есть блокировка пока распространяется на все товары выбранного склада. Следующие строки дополнительно сузят ее по номенклатуре.

          Название "Склад" должно точно совпадать с именем измерения регистра накопления. Если измерение называется СкладОрганизация, нужно писать:

          Значение Склад обычно является ссылкой на элемент справочника Склады.

          —

          Указывается источник данных, из которого будут взяты значения для ограничения блокировки.

          В вашем случае СписокНоменклатуры вероятнее всего является табличной частью документа.

          Например, табличная часть содержит строки:

          | Номенклатура | Количество |
          |—|—:|
          | Товар А | 5 |
          | Товар Б | 3 |
          | Товар В | 7 |

          После установки:

          платформа получает возможность использовать строки этой табличной части для формирования области блокировки.

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

          Вместе эти две строки означают:

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

          —

          Здесь задается соответствие между полем регистра и полем источника данных.

          Первый параметр:

          это поле пространства блокировки, то есть измерение регистра накопления.

          Второй параметр:

          это поле источника данных, то есть колонка в табличной части СписокНоменклатуры.

          Получается соответствие:

          Если в табличной части есть товары:

          то блокировка будет установлена примерно на такие комбинации:

          Остальные товары на этом складе блокироваться не будут.

          Именно поэтому источник данных здесь предпочтительнее, чем блокировка всего регистра или всего склада.

          ### Если не использовать источник данных

          Можно было бы заблокировать весь выбранный склад:

          Но тогда блокировка затронула бы все товары этого склада:

          Это избыточно. Два пользователя не смогут одновременно проводить документы даже по разным товарам одного склада.

          Например:

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

          При использовании источника данных блокируются только реально используемые товары.

          —

          Это команда фактической установки блокировки.

          До этой строки объект Блокировка только содержит описание:

          Именно вызов:

          передает это описание платформе и пытается получить блокировку.

          Если нужные данные свободны, блокировка устанавливается сразу.

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

          Блокировка действует до окончания текущей транзакции:

          — до успешной фиксации транзакции;
          — либо до отмены транзакции при ошибке;
          — либо до отката проведения.

          Она не является постоянной блокировкой данных и не записывается в регистр как отдельная информация.

          ## Что именно блокируется в вашем коде

          Если:

          а в табличной части есть:

          то логически блокируются следующие области:

          Другой склад не блокируется:

          Другой товар тоже не блокируется:

          Если другой документ работает с Товаром В, он, как правило, не будет ждать блокировку документа по Товару А.

          ## Почему блокировку устанавливают до запроса остатков

          Правильная последовательность для документа расхода:

          Почему нельзя сначала прочитать остаток, а потом установить блокировку:

          В таком случае проверка выполнялась по устаревшим данным.

          Блокировку нужно получать до чтения остатков, чтобы между проверкой и формированием движения другой документ не изменил эти же остатки.

          ## Важное условие для работы блокировки

          Регистр накопления, документ и транзакция должны работать в управляемом режиме блокировок.

          Если объект находится в автоматическом режиме, а код вручную устанавливает управляемую блокировку, может возникнуть ошибка вида:

          В конфигураторе нужно проверить свойство:

          Для документа, его регистров и используемых объектов должен быть выбран управляемый режим, если конфигурация использует явные управляемые блокировки.

          Кроме того, имена должны совпадать с метаданными:

          должно быть измерением регистра, а:

          должно быть одновременно:

          — измерением регистра ОстаткиНоменклатуры;
          — колонкой табличной части СписокНоменклатуры.

          Если в регистре измерение называется Товар, а в табличной части поле называется Номенклатура, код должен выглядеть так:

          То есть первый параметр относится к регистру, второй к источнику данных.

      Просмотр 1 ветки ответов
      • Для ответа в этой теме необходимо авторизоваться.
      База знаний 1С