Дата последнего изменения: 15.11.2023
В этом уроке разберем решение периодически встречающейся проблемы, когда при работе в административном разделе элементы инфоблока сохраняются слишком долго.
Признаки:
UPDATE b_iblock_element SET TIMESTAMP_X = TIMESTAMP_X, SHOW_COUNTER_START = ifnull(SHOW_COUNTER_START, now()), SHOW_COUNTER = ifnull(SHOW_COUNTER, 0) + 1 WHERE ID=ИД_сохраняемого_элемента
Наиболее вероятная причина - обработчик событий, посылающий http(s)-запрос к публичной детальной странице элемента, на которой в настройках компонента включено обновление счетчика просмотров.
Далее рассмотрим выявление причины подробнее на примере.
В ходе первичного анализа установлено, что тормозящий запрос - это вызов метода ClBlockElement::CounterInc. Однако данный метод вызывается только для увеличения счетчика просмотров в публичных компонентах и не должен тормозить процесс сохранение элементов.
Открываем код страницы редактирования и видим, что сохранение элемента работает через транзакции. Делается это, чтобы откатить все изменения, если на каком-то этапе сохранения произошла ошибка.
Последовательно проверяем все вызовы методов CIBlockElement::Update, обновление полей цен и товара, работу с документооборотом. , находящиеся внутри блока транзакции - есть ли на проекте обработчики событий, что именно вызывается в этих методах. Если результат отрицательный - разбираем методы детально и смотрим уже их (например, для метода CIBlockElement::Update таким является вызов CIBlockElement::UpdateSearch, а в нем - CSearch::Index).
В результате в одном из обработчиков находим http(s)-запрос к публичной детальной странице элемента. А на этой странице в компоненте Например, в компонентах Элемент каталога детально или Каталог включена опция Использовать счетчик просмотров. включено обновление счетчика просмотров. Отключаем его - все тормоза исчезают.
Вывод: при редактировании элемента мы блокируем элемент от других изменений, но обработчик вступает в конфликт (пытается обратиться к обновленному счетчику). В результате элемент, созданный в административной части сайта, сохраняется долго (или может не сохраниться вообще).
Далее в уроке для наглядности рассмотрим ожидаемый план сохранения элемента и то, как на него влияет вызов подобных обработчиков.
Ожидаемый план сохранения данных:
План сохранения данных с ранее выявленным обработчиком
...долгое ожидание...
Повторимся, что лучше не использовать в своем проекте обработчики событий, посылающие http(s)-запросы к публичной детальной странице элемента и вступающие в конфликт с выполнением транзакций.
Если по каким-либо причинам от такого обработчика избавиться нельзя, то можно воспользоваться следующими вариантами решения проблемы:
disableCounter=Y
). На самой странице параметр вызова компонента USE_ELEMENT_COUNTER
(на примере bitrix:catalog или catalog.element) меняем таким образом:
"USE_ELEMENT_COUNTER" => "Y"
"USE_ELEMENT_COUNTER" => (isset($_REQUEST['disableCounter']) && $_REQUEST['disableCounter'] === 'Y') ? 'N' : 'Y'
Этот способ проще первого, однако теряется возможность настройки компонента через визуальный редактор. Это можно поправить переносом правки в шаблон (в случае комплексного компонента).