Куда помещает данные метод ПоместитьВоВременное Хранилище()?

Это один из часто задаваемых вопросов на экзамене «1С: Эксперт по технологическим вопросам».

Подробно о методе написано на ИТС («Анализ причин роста сеансовых данных» и «Помещение данных во временное хранилище»).

Попробуем рассмотреть кратко, что такое хранилище сеансовых данных.

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

Расположение каталога сеансовых данных можно определить по ключу «/d» в командной строке запуска службы сервера.

Обычно это файлы C:\Program Files (x86)\1cv8\srvinfo\reg_номерпорта\snccntx[guid]\snccntx*.dat .

Сеансовые данные образуются не только методами «ПоместитьВоВременноеХранилище», «ПоместитьФайл», «НачатьПомещениеФайла», но и в результате работы формы: после ввода значений в поля ввода, при последующих серверных вызовах, данные сбрасываются в хранилище сеансовых данных.

Хранилище сеансовых данных параллельно существует и в памяти операционной системы. С помощью технологии mapping данные файлов snccntx*.dat частично, в необходимом размере, отображаются в оперативную память.

Сеансовые данные постепенно устаревают — при закрытии формы, сеанса пользователя или при следующем серверном вызове. Это зависит от способа помещения данных в хранилище сеансовых данных.

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

Объём создаваемых сеансовых данных можно определить с помощью анализа технологического журнала. Для этого требуется включить сбор событий CALL, SCALL и CONN со следующими настройками:

При этом свойство InBytes события CALL будет показывать сеансовые данные в байтах.

Решение билета 1 (аттестация 1С: Эксперт по технологическим вопросам)

Условие билета

Вопрос 1.1

Вопрос имеет несколько решений в зависимости от версии платформы 1С и режима управления блокировкой данных в конфигурации.

В версии платформы <8.2.14 константы хранятся в одной таблице _Consts в одной строке в разных колонках:

Таблица _Const в 1С 8.2.13

Начиная с 1С 8.2.14 для каждой константы определена отдельная таблица:

Таблица _Const в 1С 8.2.14

Рассмотрим, какие блокировки будут накладываться при чтении в транзакции и вне транзакции в СУБД MS SQL 2014 при автоматическом режиме управления блокировкой данных:

1С 8.2.13 Чтение константы в транзакции методом Получить() в автоматическом режиме
Блокировки 8.2.13 чтение в транзакции методом Получить
Установлена разделяемая блокировка (S) на единственную запись в кластерном индексе _Consts_ByKey_B таблицы _Consts, а также блокировки намерения IS на страницу индекса _Consts_ByKey_B и на всю таблицу.
1С 8.2.13 Чтение константы в транзакции запросом в автоматическом режиме
Блокировки 8.2.13 чтение в транзакции запросом
Установлена разделяемая блокировка диапазона RangeS-S на единственную запись кластерного индекса _Consts_ByKey_B, блокировки намерения IS на страницу кластерного индекса _Consts_ByKey_B и на всю таблицу.

Переведём конфигурацию в управляемый режим, включим в ТЖ отслеживание событий TLOCK и SDBL к исследуемой базе. Проведём аналогичный эксперимент по чтению в транзакции константы методом Получить() и запросом.

После выполнения запроса установленных управляемых блокировок 1С и блокировок СУБД не зафиксировано.

Во время работы метода Получить() и выполнения запроса на строки, выбираемые запросом, накладывалась S-блокировка. После чтения строк данная блокировка снималась.

Изменим версию совместимости на 8.2.16. Повторим эксперимент в автоматическом режиме:

1С 8.2.16 Чтение константы в транзакции методом Получить() в автоматическом режиме
Блокировки 8.2.16 чтение в транзакции методом Получить
Установлена S-блокировка на запись кластерного индекса _Const1832_ByKey_B, блокировки намерения IS на страницу кластерного индекса и на всю таблицу. Видно, что для каждой константы используется своя таблица.
1С 8.2.16 Чтение константы в транзакции запросом в автоматическом режиме
Блокировки 8.2.16 чтение в транзакции запросом
Установлена разделяемая блокировка диапазона RangeS-S на единственную запись кластерного индекса _Const1832_ByKey_B, блокировки намерения IS на страницу кластерного индекса _Consts_ByKey_B и на всю таблицу.

При использовании платформы 8.3 без режима совместимости с 8.2 в управляемом режиме блокировок чтение в транзакции и без транзакции неблокирующее, вследствие использования уровня изоляции Read Commited Snapshot (RCS).

В автоматическом режиме блокировок в 8.3 без режима совместимости с 8.2 будут наложены аналогичные S и RangeS-S-блокировки, как и в 8.2 (см. иллюстрации выше).

В случае, если транзакции не используются, чтение в 8.2.13, 8.2.14 и 8.3 будет неблокирующее.

Таким образом, можно заполнить следующую таблицу-ответ на вопрос билета 1:

Действие 1 Действие 2 8.2.13 8.2.14 8.3
Запись Конст1 Запись Конст2 + +
Чтение Конст1 Запись Конст2 + +
Чтение Конст1 Чтение Конст2 + + +

Вопрос 1.2

Ответ на вопрос зависит от режима управления блокировкой в конфигурации и от версии платформы.

В случае автоматического режима и платформы 8.2 будет следующая картина:

Разделяемые блокировки после метода ПолучитьОбъект()
Разделяемые блокировки после метода ПолучитьОбъект() в автоматическом режиме

Исключительные блокировки после метода Записать() в автоматическом режиме
Исключительные блокировки после метода Записать() в автоматическом режиме

Поведение платформы в автоматическом режиме на платформе 8.3 будет аналогично.

Рассмотрим управляемый режим блокировок.

Исключительные блокировки в управляемом режиме
Исключительные блокировки в управляемом режиме после метода Записать()

Также в управляемом режиме при выполнении метода Записать() установилась управляемая блокировка на пространство Reference7.REFLOCK .

Данный код может привести к взаимоблокировке с видом «повышение уровня изоляции ресурса» вследствие следующих действий:

Если две параллельные транзакции в автоматическом режиме установят разделяемую S-блокировку на один и тот же ресурс, выполнив запрос в транзакции (методом ПолучитьОбъект()), то в последствии каждая транзакция будет вынуждена ждать другую для установки исключительной X-блокировки. Менеджер блокировок СУБД распознает это и возникнет взаимоблокировка.

Взаимоблокировка СУБД вследствие повышения уровня изоляции ресурса

Взаимоблокировка СУБД вследствие повышения уровня изоляции ресурса

Для решения проблемы взаимоблокировки можно пойти несколькими путями:

  1. Получать ссылку на объект номенклатуры запросом с опцией для ИЗМЕНЕНИЯ. Например, так:
  2. Перевести конфигурацию в управляемый режим блокировок. В этом случае разделяемая S-блокировка будет снята в процессе выполнения запроса после чтения строк данных (для 8.2) и не будет установлена вообще (для 8.3).
  3. Использовать методы объектной блокировки (для интерактивного режима). В этом случае метод Заблокировать() вызовет исключение, если данный объект уже заблокирован другим пользователем:

Вопрос 1.3

Особенностями автоматического режима управления блокировкой данных является следующее:

  1. При чтении запросом с опцией для ИЗМЕНЕНИЯ пустой таблицы будет заблокирована RangeS-U-блокировкой пустая запись индекса. любая другая запись будет «соседней» для пустой записью и не может быть вставлена в таблицу.
  2. Блокировка на соседних записях в регистре также вызвана особенностью Range-блокировок, которые не только блокируют считанный/записанный диапазон, но и ещё одну строку ниже этого диапазона.

Для решения указанных проблем требуется перевод конфигурации в управляемый режим, в котором нет Range-блокировок.

Для этого нужно выполнить следующие действия:

  1. Сделать копию рабочей базы.
  2. В копии рабочей базы установить свойство «Режим управления блокировкой» в значение «Управляемый».
  3. Найти в коде конфигурации все места, где выполняется чтение итогов регистра и последующая запись в этот регистр.
  4. Использовать в этих местах исключительную управляемую блокировку 1С на записываемые данные или использовать новую методику проведения (сначала записывать данные, потом контролировать итоги по регистру). В последнем случае рассмотреть возможность использования разделения итогов и опции БлокироватьДляИзменения набора записей.
  5. Сделать резервную копию рабочей базы.
  6. Объединить конфигурации.
  7. Провести тестирование.

Ответы на 1С: Профессионал по технологическим вопросам с комментариями

В процессе подготовки к аттестации «1С: Эксперт по технологическим вопросам» я наткнулся на интересный сайт http://debug1c.ru, на котором присутствуют ответы на сертификацию «1С: Профессионал по технологическим вопросам» с подробными комментариями, ссылками на авторитетные источники.

Раздел 1

Раздел 2

Раздел 3

Раздел 4

Раздел 5

Раздел 6

Раздел 7

Раздел 8

Раздел 9

Раздел 10

Раздел 11

Раздел 12

Раздел 13

Раздел 14

На случай исчезновения данного сайта был создан архив ответов здесь в Google Docs.

Упрощение работы с таблицей значений при добавлении строк

Часто требуется программно добавить несколько строк в таблицу значений.

Обычно программисты делают это так:

В случае, когда требуется заполнять в коде только одну колонку таблицы значений, оптимальнее добавлять строки так:

В ходе теста оценки производительности данный сокращенный способ добавления строк в таблицу значений на платформе 8.3.6.2530 работает на 16.45% быстрее.

Код теста оценки производительности:

 

Влияние конструкции ВЫРАЗИТЬ на SQL-запрос и его план на поля не составных типов

Рассмотрим влияние конструкции ВЫРАЗИТЬ, если её применить к полю обычного ссылочного не составного типа.

Пусть выполняется запрос без ВЫРАЗИТЬ и с ВЫРАЗИТЬ по отношению к полю выборки:

В процессе выполнения строки Запрос.Выполнить() будут выполнены следующие запросы SQL:

В тексте запроса SQL различий нет.

Сравним план запроса:

Очевидно, что план запроса тоже одинаков.

Вывод: для приведения типа значения в таблице значений, передаваемой в качестве параметра запроса, допустимо использовать конструкцию ВЫРАЗИТЬ.