Обеспечение уникальности реквизита справочника. #754874


#0 by kdenis
Доброго дня! 8.3.6 Прошу помощи в решении задачи обеспечения уникальности реквизита справочника. Есть справочник Штрихкоды (Штрихкод - строка15, ТипШтрихкода - ПланВидовХарактеристик.ТипыШтрихкодов, прочие реквизиты...). Необходимо обеспечить уникальность реквизита Штрихкод при многопользовательской работе. Элементы справочника в большинстве своем создаются массово обработкой (от 300 штук), запускать процесс создания могут несколько пользователей одновременно. Алгоритм создания каждого элемента: 1. Создаем элемент справочника. 2. Запросом получаем текущий максимальный Штрихкод. 3. Присваиваем новый штрихкод созданному в 1 элементу (НовыйШтрихкод = Штрихкод + 1) 4. Записываем элемент справочника. 5. В событии ПередЗаписью запросом контролируем уникальность реквизита Штрихкод, в случае, если он не уникален - Отказ (необходимо в том случае, если элемент создавался вручную, а не обработкой) Проблема. Если несколько пользователей запускают создание штрихкодов одновременно или с небольшим интервалом, возникает такая ситуация: 1. Два пользователя одновременно получили запросом текущий максимальный штрихкод. 2. Вычислили новый штрихкод. 3. Записали каждый свой элемент с одинаковым штрихкодом. 4. У того пользователя, который записал элемент первым проблем не возникло. Другой же пользователь в обработчике ПередЗаписью получил отказ, т.к. его штрихкод уже содержится в справочнике. Прошу тех, кто решал подобную задачу поделиться опытом, а тех кто не решал - идеями. Мои мысли: Вычисление нового штрихкода и запись элемента делать в транзакции, и в начале этой транзакции заблокировать справочник целиком для чтения другим транзакциям. Не могу придумать механизм блокировки справочника целиком. Изучал объект БлокировкаДанных, но в документации не нашел примеров блокировки именно справочника целиком. Если есть те, кто разбирался с этим объектом, подскажите как решить задачу с помощью него.
#1 by Garykom
а заснуть ШК в код? с уникальностью оных?
#2 by mehfk
Создавай штрихкоды в обратном порядке.
#3 by Garykom
или в регистр сведений ШК заносить а не в справочник
#4 by бомболюк
получение текущего макс. штрихкода и его изменение делаем в транзакции, получение делаем запросом с хинтом ДЛЯ ИЗМЕНЕНИЯ.
#5 by ДенисЧ
транзакции не предлагать?
#6 by kdenis
Нет, штрихкод может быть различной длины (EAN8, EAN13). Автоматическое создание следующего невозможно. Т.е. новый штрихкод снова получить запросом. Следовательно, задача не решена. Не понял, как это поможет мне контролировать уникальность. А таблицу регистра сведений можно заблокировать целиком для чтения другими транзакциями? А разве при этом блокировка не снимается по окончании выполнения запроса? Запись-то происходит после него. Конечно предлагать, только по возможности пояснить, как заблокировать справочник в одной транзакции для чтения его другими транзакциями.
#7 by бомболюк
блокировка снимается по окончании транзакции.
#8 by rphosts
самый надёжный способ - блокировать запуск обработки несколькими пользователями.
#9 by kdenis
По-моему предложение ДЛЯ ИЗМЕНЕНИЯ не защитит таблицу от чтения другими транзакциями. Т.е. несколько транзакций смогут получить одинаковый штрихкод. Так?
#10 by kdenis
Это понятно, но работа этих пользователей и заключается именно в использовании этой обработки. И неплохо было бы программно разрулить эту очередь, а не заставлять пользователей договариваться.
#11 by rphosts
ок, если у кого-то выполняется генерация кодов - другой по клику на эту кнопку получит сообщение, что покури пару сек и повтори.
#12 by Garykom
ну тогда сделать регистр сведений "зарезервированные номера ШК" т.е. сначала резервируем номера, если не получилось то читаем что там и снова резервируем и только потом создаем ШК
#13 by бомболюк
если кто то читает с ДЛЯ ИЗМЕНЕНИЯ, то ты уже не прочитаешь с ДЛЯ ИЗМЕНЕНИЯ, оно для этого и придумано.
#14 by Garykom
+ еще можно извратиться с регламентным заданием или еще каким сервисом )) который будет в единственном экземпляре на базу запускаться и выдавать номера ШК по запросу
#15 by Garykom
+ т.е. нечто вроде очереди, куда помещается номер (код, гуид и т.д.) и типШК, с пустым значением шк далее отрабатывает регламентное и читаем оттуда заполненные (присвоенные) ШК
#16 by torgm
Выделяй манагерам диапазоны по 50-100-200 штрихкодов (в зависимости от твоих условий) , если использовали то следующий.
#17 by dmpl
Процедура на сервере ПолучитьСледующийШтрихКод, которая блокирует некий объект (один на всех) и раздает централизованно номера.
#18 by kdenis
За идею спасибо. Рассматривал похожий вариант на крайний случай, но не хотелось дублировать данные. Вот это поизучаю подробнее и потестирую. Не догадывался, что два запроса могут вытеснить друг друга. Спасибо. Пока единственный предложенный способ, опирающийся именно на блокировки. Слишком загонно. Но спасибо. Такая процедура есть, в ней запрос с выборкой максимального штрихкода. Остается открытым вопрос как заблокировать "некий объект", в моем случае справочник штрихкодов.
#19 by itlikbez
заблокировать можно блокировкой.
#20 by FIXXXL
А может нумератор сэмулировать? Константа к примеру "макс.номер". Ее и блокировать до конца записи элемента справочника.
#21 by DCKiller
Лучше сделай обработку исключительной ситуации, чтобы в случае, если такой ШК уже кто-то ввел, программа автоматически добавляла 1 к ШК, который не хочет записываться, и в таком виде сохраняла его в справочнике, предварительно уведомив юзера. Можно даже сделать, чтобы в этом случае у юзера выдавалось на экран подтверждение, нужно ли записать элемент с таким ШК.
#22 by FIXXXL
и пока юзер чай пьет и +1 и +еще сто номеров уже займут :)
#23 by kdenis
Спасибо за участие. Эта идея тоже в резерве на крайний случай, наряду с регистром штрихкодов. На самом деле рассчитывал обойтись блокировкой справочника, а не изобретать костыли. Но раз заведомо рабочего примера с блокировкой никто не дал, возможно платформа не позволяет решить задачу встроенными механизмами.
#24 by ЧеловекДуши
На УФ блокировки справочника уже не блокируют :)
#25 by kdenis
Это вопрос или утверждение?
#26 by DCKiller
Нефиг столько времени пить чай.
#27 by Bober
В 8.3 реализовали возможность накладывать блокировки на реквизиты справочников. Перед записью накладываешь блокировку на спр по реквизиту и запросом проверяешь уникальность (за исключением ссылки на текущий элемент).
#28 by kdenis
Уже ближе к истине. Можете подсказать, где прочитать про эту возможность?
#29 by Bober
в конфигураторе, синтакс-помощник, раздел общие объекты - Управление блокировкой данных. там и примеры кода есть.
#30 by kdenis
Читал про объект БлокировкаДанных и в СП, и в Профессиональной разработке в системе "1С:Предприятие 8". Везде написано как по шаблону: 1. Создать объект. 2. Добавить элемент, указав пространство блокировки. 3. Установить значение, которое будет заблокировано. 4. Установить режим. 5. Заблокировать Про пункт 3 нигде явно не написано, что будет, если не указывать значение. Заблокируется ли полностью пространство (в моем случае справочник). Вот этой информации не достает. Тесты (насколько возможно протестировать параллельную работу) показали, что этого достаточно. Но хотелось бы именно теоретических обоснований для публикации решения в продуктив. "Рабочее" (в кавычках, т.к. выводы по результатам эксперимента на файловой СУБД и PostgreSQL) решение следующее: 1. Начинаем транзакцию (РежимУправленияБлокировкойДанных.Управляемый) 2. Объектом БлокировкаДанных устанавливаем блокировку (Имя пространства имен - мой справочник). Значение не указываем. 3. Запросом вычисляем текущий штрихкод, и вычисляем значение нового. 4. Создаем элемент справочника, присваиваем штрихкод и записываем его. 5. Фиксируем транзакцию. На сколько это решение действительно рабочее неизвестно, т.к. теоретического обоснования найти не удалось.
#31 by asady
может тупо генерить штрихкоды как уиды? - в смысле отказаться от автоинкремента.
#32 by kdenis
Спасибо и за эту идею.
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С