Как происходит обновление констант в 1С и можно ли использовать их в качестве счетчиков номеров?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке на платформе 1С:Предприятие часто возникает вопрос о том, насколько быстро изменения, внесенные одним пользователем, становятся доступны другим. Особое место в этом вопросе занимают константы. В этой статье мы подробно разберем механизмы чтения и записи констант, выясним, почему «мгновенное» обновление не всегда происходит на уровне интерфейса, и проанализируем, почему использование константы в качестве счетчика — это опасная архитектурная практика.

Механизм обновления данных между сеансами

Начнем с базового принципа работы платформы. Когда один пользователь записывает новое значение константы, данные физически попадают в таблицу базы данных (обычно это таблица _Consts). Для другого пользователя эти данные становятся доступны сразу же, как только его сеанс инициирует чтение этой константы из базы данных. Однако понятие «сразу» в 1С имеет свои нюансы, связанные с тем, как именно программный код обращается к данным.

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

  1. Использование менеджера констант: Метод Константы.ИмяКонстант.Получить() обращается к базе данных. Если значение в базе уже изменено и транзакция записи завершена, второй пользователь получит актуальное значение.
  2. Использование запроса: Это самый надежный способ получить текущее состояние данных «здесь и сейчас», так как запрос всегда обходит объектный кэш платформы.

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

Где может «застрять» старое значение: механизмы кэширования

Даже если в таблице SQL значение обновилось, пользователь может продолжать видеть старые данные. Разберем по шагам, почему это происходит:

Параметры сеанса. Часто для повышения производительности значения констант считываются в параметры сеанса при запуске (в модуле сеанса). Параметры сеанса живут на протяжении всей работы пользователя. Если вы изменили константу, а код системы продолжает обращаться к ПараметрыСеанса.ТекущийСчетчик, значение не обновится до тех пор, пока сеанс не будет перезапущен или параметр не будет перезаписан программно в текущем сеансе.

Функциональные опции (ФО). Если константа является источником для функциональной опции, ситуация усложняется. Платформа активно кэширует значения ФО для отрисовки интерфейса. Чтобы изменения вступили в силу (например, появилась скрытая кнопка), может потребоваться вызов метода ОбновитьИнтерфейс(). В некоторых случаях изменения видны только после повторного входа в программу.

Повторное использование возвращаемых значений. Проанализируем работу общих модулей. Если чтение константы обернуто в функцию модуля, у которого включено свойство «Повторное использование возвращаемых значений» (на время вызова или на время сеанса), платформа вернет старое значение из своего внутреннего кэша, не обращаясь к СУБД.

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

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

Блокировки базы данных. В 1С все константы хранятся в одной общей таблице. При записи константы происходит блокировка. Если одновременно 10 пользователей попытаются «взять номер» и обновить константу, они выстроятся в очередь (lock contention). В худшем случае это приведет к ошибкам превышения времени ожидания блокировки. Система начнет «тормозить» на пустом месте.

Транзакционные коллизии. Представим ситуацию:


// Псевдокод инкремента
ТекущийНомер = Константы.НомерПечатнойФормы.Получить();
НовыйНомер = ТекущийНомер + 1;
Константы.НомерПечатнойФормы.Установить(НовыйНомер);
Если два пользователя одновременно выполнят этот код, велика вероятность, что они оба прочитают значение «10», оба вычислят «11» и оба попытаются записать «11». Тот, кто на долю секунды опоздал, либо получит ошибку блокировки, либо (что еще хуже в некоторых режимах) перезапишет значение тем же самым числом, и вы получите два документа с одинаковыми номерами.

Рекомендуемые альтернативы для реализации счетчиков

Если нам необходимо реализовать надежный счетчик, который работает быстро и без конфликтов, рассмотрим следующие варианты:

  1. Справочник вместо константы. Создадим отдельный справочник (например, СчетчикиПечати), где каждый элемент — это отдельный счетчик. При записи элемента справочника блокируется только одна конкретная строка, а не вся таблица «всех настроек системы» (как в случае с константами). Это значительно повышает параллельность работы.
  2. Использование механизмов автонумерации. Платформа 1С имеет встроенные механизмы нумерации для документов и справочников. Они оптимизированы для работы в транзакциях и минимизируют риск получения дублей. По возможности, стоит использовать именно их, создавая технические документы для регистрации факта печати.
  3. Последовательности. Для задач, где важен строгий порядок, можно использовать объекты типа Последовательность, хотя это более тяжеловесный механизм.

Как правильно считывать актуальные данные

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


Функция ПолучитьАктуальноеЗначениеКонстанты() Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Константы.МояВажнаяНастройка КАК Значение
        |ИЗ
        |	Константы КАК Константы";
    
    РезультатЗапроса = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    
    Если ВыборкаДетальныеЗаписи.Следующий() Тогда
        Возврат ВыборкаДетальныеЗаписи.Значение;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Этот метод гарантирует, что вы обращаетесь напрямую к таблице базы данных. Однако помните, что частое использование запросов к константам в циклах может создать излишнюю нагрузку на SQL-сервер. Всегда ищите баланс между актуальностью данных и производительностью системы.

Резюме

Подведем итоги нашего анализа. Значение константы обновляется в базе данных мгновенно, но механизмы оптимизации 1С (кэширование интерфейса, параметры сеанса) могут скрывать это изменение от пользователя до определенных событий. Использовать константы для счетчиков — плохая практика из-за блокировок таблицы _Consts. Для этих целей лучше использовать элементы справочников или типовую автонумерацию объектов платформы.

← На главную