Методические рекомендации по конфигурированию
Прикладные объекты
13.06.2013
Основные принципы работы автонумерации описаны в разделе "Автонумерация". В этом разделе описываются особенности работы механизма автонумерации при одновременной работе нескольких пользователей.
Будем рассматривать этот вопрос на примере справочника. Для всех остальных объектных данных автонумерация реализована аналогично.
Механизм автонумерации опирается, прежде всего, на данные, хранящиеся в базе данных в той таблице, в которой собственно и хранятся объекты. При формировании нового кода выполняется поиск существующего максимального кода в справочнике. Поиск выполняется с учетом указанного префикса, то есть в пределах записей с указанным префиксом в начале кода. Так как для поля "Код" всегда поддерживается индекс, то поиск выполняется достаточно быстро.
Следует учитывать, что при этом анализируются именно имеющиеся записи. То есть, если некоторый объект, имеющий максимальный код, будет удален, то система предложит этот код при очередном обращении за новым кодом. Но если удален объект с некоторым не максимальным кодом или просто имеются пропущенные коды в имеющихся объектах, то такие коды не будут предлагаться. Если необходимо уметь заполнять пропущенные коды, то не нужно пользоваться автонумерацией, а нужно реализовывать собственный алгоритм формирования кода в конфигурации.
Заметим, что формирование нового кода не происходит при создании нового объекта. Объект может создаваться не потому, что вводится новая информация а, например, в ходе переноса информации из другой информационной базы, или в ходе автоматической загрузки данных из внешних источников с уже известными кодами. Соответственно нет смысла тратить хотя и небольшое, но все-таки лишнее время на генерацию нового кода, если он будет тут же замещен. Соответственно установку нового кода нужно вызывать в явном виде (метод УстановитьНовыйКод()). При этом в форме элемента расширение формы автоматически формирует новый код при открытии формы нового элемента. Это действие не более чем сервис, поддерживаемый расширением формы – оно аналогично вызову метода УстановитьНовыйКод() в обработчике открытия формы.
Таким, образом, разработчик прикладного решения должен вызывать установку нового кода именно тогда, когда этот необходимо. В противном случае, будет иметь место, лишнее обращение к базе данных и возможны лишние блокировки.
Можно также рекомендовать внимательно относиться к месту вызова метода УстановитьНовыйКод(). Вызов метода в транзакции может повлечь нежелательные блокировки.
Для обеспечения корректной работы автонумерации при многопользовательской работе система обеспечивает механизм блокировки полученных новых кодов с момента их установки до момента записи объекта или уничтожения значения типа СправочникОбъект из памяти.
Это можно проиллюстрировать следующим примером:
Копировать в буфер обмена//Фрагмент 1 Объект1 = Справочники.Номенклатура.СоздатьЭлемент(); Объект1.УстановитьНовыйКод(); Сообщить(Объект1.Код); //4753 Объект2 = Справочники.Номенклатура.СоздатьЭлемент(); Объект2.УстановитьНовыйКод(); Сообщить(Объект2.Код); //4754 //Фрагмент 2 Объект1 = Справочники.Номенклатура.СоздатьЭлемент(); Объект1.УстановитьНовыйКод(); Сообщить(Объект1.Код); //4753 Объект1 = Неопределено; Объект2 = Справочники.Номенклатура.СоздатьЭлемент(); Объект2.УстановитьНовыйКод(); Сообщить(Объект2.Код); //4753 //Фрагмент 3 Объект1 = Справочники.Номенклатура.СоздатьЭлемент(); Объект1.УстановитьНовыйКод(); Сообщить(Объект1.Код); //4753 Объект1.Записать(); Объект2 = Справочники.Номенклатура.СоздатьЭлемент(); Объект2.УстановитьНовыйКод(); Сообщить(Объект2.Код); //4754
В первом фрагменте, так как в памяти существовал объект с установленным новым кодом, то при получении кода для второго объекта система пропустила заблокированный код.
Во втором фрагменте, так как первый объект уже не существовал, новому объекту был присвоен тот же код, что и первому. Здесь надо уточнить, что таким образом система действует, если свойство конфигурации "Режим автонумерации объектов" установлено в значение "Освобождать автоматически". Если это не так, то система для второго объекта не будет переиспользовать номер и установит для Объект2 код 4754.
В третьем фрагменте второму объекту присвоен код отличный от кода первого объекта, так как первый объект уже был записан.
Таким образом, при установке нового кода система ищет максимальный существующий код, формирует на его основе следующий код и проверяет, что его нет среди заблокированных кодов. Если он есть среди заблокированных кодов, то формируется следующий код и снова ищется среди заблокированных. Так происходит, пока не будет обнаружен свободный код. Он устанавливается в качестве кода элемента и блокируется.
Разумеется, этот механизм, прежде всего, ориентирован на формирование новых кодов при интерактивном вводе данных пользователями. Если один пользователь начал вводить элемент в форме, а другой в это время так же вызвал ввод элемента, то новому элементу присвоится код отличный от того, который присвоен элементу, вводимому первым пользователем.
Следует заметить, что если для справочника используется автонумерация и код не установлен, то в момент записи система выполнит автоматически формирование нового кода. Соответственно, при программном формировании элементов нет необходимости в вызове метода УстановитьНовыйКод(). Однако вызов этого метода может быть полезен, чтобы вынести формирование нового кода из транзакции записи элемента.