Решение билета 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. Провести тестирование.
Поделиться