Добрый день, коллеги.
Написал алгоритм формирования уникального артикула, в целом работает исправно , за исключением параллельных вызовов(когда два и более клиента вызывают метод одновременно, то всем вернется один и тот артикул), каким образом с такими проблемами справляются в 1с?
Алгоритм простой: запросом выбираем Артикул из таблицы номенклатура, плюсуем к нему 1 и записываем. Вызов метода "НовыйАртикул()" происходит в обработчике "ПриУстановкеНовогоКода".
---
Все, задачу решил.
Если кому-то еще надо будет, то вот:

```1c
    //Функция общего модуля которая делает запрос и выбирает максимальный из существующих
    Функция МаксимальныйНомерАртикула(Префикс,Характеристика = Ложь) Экспорт

    Попытка
    БлокировкаДанных = Новый БлокировкаДанных;
    БлокировкаКонстанты = БлокировкаДанных.Добавить("Константа.УА_Артикул");
    БлокировкаДанных.Заблокировать();
    Исключение
    //Сообщить("Объект уже заблокирован");
    Возврат Ложь;
    КонецПопытки;
    //
    // тут код получения нужных данных и их возврата
    //
    КонецФункции

    //Код в объекта где требуется получить уникальный номер
    Процедура УстановитьАртикул()
    НачатьТранзакцию(); //Использование транзакций обязательно для использования блокировки объекта
    Артикул = Ложь;
    Пока НЕ Число(Артикул) Цикл //Артикул возвращается строкой, а строка не может быть преобразована к
    //булево, поэтому преобразуем к числу, а число легко преобразуется к
    //булево, нулевого артикула у меня быть не может.
    Артикул = Число(УА_ОбщийСервер.МаксимальныйНомерАртикула("Префикс-"))+1;
    КонецЦикла;
    Сообщить("Артикул :"+Артикул);
    ЗафиксироватьТранзакцию(); //Возможно эту часть можно опустить , но у меня эта функция во внешней
    //обработке , поэтому явно завершаю транзакцию.
    КонецПроцедуры
```
---
каким образом с такими проблемами справляются в 1с?
Исключительной транзакционной блокировкой
---
Всего справочника? ведь по сути мы только читаем максимальное значение артикула и сам объект не меняем и тут либо блокировать весь справочник, что 100% является не верным решением, либо устанавливать эксклюзивную (исключительную) блокировку на объект содержащий максимальный артикул до завершения транзакции записи текущего элемента. А может есть еще какие-то варианты решения?
---
Не хочешь справочник - пользуй Константу.
---
Можно использовать константу для хранения значения артикула, в это случае блокировать будет только она.
---
Шас скажет, что артикул не сквозняком по справочнику, а префиксуемый в зависимости от обстоятельств - вида номенклатуры, родителя и т.д.
---
так и есть, но не вижу проблемы в этом. Еще не реализовал, но совет выглядит подходящим, спасибо!
Только если мне память не изменяет все константы хранятся в одной таблице и блокироваться будет вся таблица целиком, верно?
---
константы хранятся в одной таблице и блокироваться будет вся таблица целиком Это какая-то проблема?
---
Вроде разделили. Каждая константа в отдельной таблице.
---
Да, Вы правы.
Способ хранения констант в 1С:Предприятие 8 менялся в зависимости от версии платформы. Так, в платформе до версии 8.2.14 (или платформах выше версии, но с включенным режимом совместимости 8.2.13 и ниже), константы хранятся в одной таблице СУБД, начиная с версии 8.2.14, для каждой константы создается своя таблица СУБД. Данное изменение было сделано для увеличения параллельности работы пользователей.
---
В общем, решил сделать так: при старте системы получаем список возможных артикулов, для каждого из них формируем текущее максимальное значение и сохраняем в структуру , а дальше при каждом вызове этой процедуры возвращаем +1, не забывая увеличивать максимальный номер в структуре. Если это не полностью исключит возникновение дублей, то как минимум снизит количество таких ошибок, мне думается. Если не поможет, то буду мутить с константами и блокировками.
---
И ты умеешь хранить эту структуру для всех пользователей из разных сеансов одновременно? Или ты научился блокировать структуру от других пользователей?
Чем отличается "хранение и +1 в структуре" от "хранение и +1 в справочнике"?
---
Вопрос про блокировку структуры и "для всех сеансов одновременно" хороший. Я почему-то подумал, что оно там разок скомпилируется и будет висеть, типа как синглтон в других языках, но чувствую, ошибся тут. А что касается чем структура от справочника отличается, так ответ очевиден: из справочника мы получаем эти данные запросом и чем больше элементов, тем дольше это все выполняется, а в структуре просто плюсуем и все.
---
И по факту даже если мы блокируем константу в исключительном режиме мы все равно можем ее без проблем читать, не можем только изменить ее значение до момента пока первая транзакция не завершится. Так-что все наши рассуждения тут бесполезны в контексте решения поставленной задачи.
проверял след образом: Есть процедура которая получает максимальный номер артикула, добавил в нее блокировку константы, после блокировки установил точку останова. Накидал внешнюю обработку для установки и чтения нужной константы. Запускаю получение нового артикула, выполнение стопорится где нужно, из другого сеанса запускаю обработку, читаю константу - без проблем читается, пытаюсь записать - висит, завершаю транзакцию(снимается блокировка) обработка получает доступ к установке значения константы. Так что вариант не рабочий, к сожалению.
---
Вижу только одно решение на текущий момент, при условии, что нигде ничего не упустил из вида: использовать константу в качестве семафора. Заходит в процедуру общего модуля, проверяем нет ли блокировки на константе, если нет, значит никто сейчас не пытается получить артикул, устанавливаем блокировку, формируем новый номер, транзакция завершается, блокировка снимается и тогда уже след поток сможет ее заблокировать. Другие потоки в цикле ждут освобождения. Надеюсь, это ничто не помешает реализовать.
---
Все, задачу решил.
Если кому-то еще надо будет, то вот:

```1c
    //Функция общего модуля которая делает запрос и выбирает максимальный из существующих
    Функция МаксимальныйНомерАртикула(Префикс,Характеристика = Ложь) Экспорт

    Попытка
    БлокировкаДанных = Новый БлокировкаДанных;
    БлокировкаКонстанты = БлокировкаДанных.Добавить("Константа.УА_Артикул");
    БлокировкаДанных.Заблокировать();
    Исключение
    //Сообщить("Объект уже заблокирован");
    Возврат Ложь;
    КонецПопытки;
    //
    // тут код получения нужных данных и их возврата
    //
    КонецФункции

    //Код в объекта где требуется получить уникальный номер
    Процедура УстановитьАртикул()
    НачатьТранзакцию(); //Использование транзакций обязательно для использования блокировки объекта
    Артикул = Ложь;
    Пока НЕ Число(Артикул) Цикл //Артикул возвращается строкой, а строка не может быть преобразована к
    //булево, поэтому преобразуем к числу, а число легко преобразуется к
    //булево, нулевого артикула у меня быть не может.
    Артикул = Число(УА_ОбщийСервер.МаксимальныйНомерАртикула("Префикс-"))+1;
    КонецЦикла;
    Сообщить("Артикул :"+Артикул);
    ЗафиксироватьТранзакцию(); //Возможно эту часть можно опустить , но у меня эта функция во внешней
    //обработке , поэтому явно завершаю транзакцию.
    КонецПроцедуры
```
---
Сообщение было скрыто модератором.
---
Коллеги, поздравляю - у нас тут новая гениальная обиженка завелась!