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