Статья о том, как устроен объект конфигурации 1С:Предприятие 8 "План обмена", в том числе на уровне СУБД SQL Server. Анализируются особенности его использования при управляемом режиме блокировок.
(5) Прошу прощения, но Вы бы не могли уточнить, что конкретно имеется ввиду? Например, я понял вопрос так: есть 100 входящих сообщений обмена для центральной базы. Вероятно это РИБ. Если каждое сообщение имеет по 1 объекту, то я не вижу в этом вообще никакой проблемы ... Дайте, пожалуйста, цифры.
(5) Если отвечать на Ваш вопрос глобально, то, при условии, что были исчерпаны все варианты оптимизации планов обмена, нужно использовать альтернативные варианты. Например, можно использовать свою реализацию регистрации изменений. Это как минимум. Некоторые размышления по этому поводу я зафиксировал здесь. Есть и другие публикации по этому поводу. Ссылки на них можно найти в моём профиле.
В ближайшее время я планирую сделать ещё пару публикаций на тему того как можно оптимизировать работу планов обмена. Если проблемы серьёзные и требуется частная консультация, то я готов оказать посильную помощь. Пишите в личку.
(9) Тут не так много мест где будут отличия. Пожалуй это все те места, где выполняется команда SELECT. Если Вы хорошо понимаете разницу между READ COMMITED (автоматический режим) и READ COMMITED SNAPSHOT (управляемый режим), то без труда поймёте где и какая разница возникает.
Если отвечать упрощённо, то разница между этими двумя режимами такова, что:
1. При чтении данных:
в первом случае мы получаем версию записи после её изменения в другой транзакции. При этом мы ждём её завершения (нас блокируют - мы ждём, чтобы прочитать). А в случае со snapshot, мы получаем версию записи, которая была до начала второй транзакции. При этом мы ничего не ждём и допускаем "грязное чтение".
2. В процессе чтения данных:
в первом случае мы блокируем транзакции, которые желают изменить данные, которые мы читаем (мы блокируем - нас ждут, чтобы изменить). А в случае со snapshot мы никого не блокируем.
Некоторые могут подумать, что в первом случае прочитанные нами данные блокируются до конца транзакции, но это не так. Уточняю: речь идёт о первом случае (автоматический режим блокировок), когда опция read_commited_snapshot на уровне базы данных имеет значение OFF (выключено).
Это зависит от режима изоляции транзакции. В случае с планами обмена используется режим изоляции транзакции SQL Server по умолчанию, а он чаще всего равен READ COMMITED, то есть данные блокируются только на время их чтения.
То есть одна запись блокируется пока она читается в выборку, затем блокировка снимается, делается попытка получить разрешение на чтение следующей записи, устанавливается блокировка чтения и читается следующая запись. И так до тех пор, пока все, попавшие в условие отбора, записи не будут прочитаны.
(13) Коротко отвечу всё же:
READ COMMITTED - это уровень изоляции транзакций, как правило, используемый SQL Server.
read_committed_snapshot - это опция уровня базы данных, которая может изменять поведение уровня изоляции READ COMMITTED, принятое по умолчанию. По умолчанию read_committed_snapshot = OFF. Однако при включении управляемого режима блокировок 1С переключает это значение в положение ON. Это меняет поведение уровня изоляции транзакций READ COMMITTED принятое по умолчанию.
Интересная статья, для полноты не хватает описания того как работает платформа при использовании: ЗаписатьИзменения, и особенно в части работы параметра "ЭлементовВТранзакции".
(18) Можно легко предположить что будет. При управляемых блокировках SEL ECT будет выполняться как READ COMMITTED SNAPSHOT, так как BEGIN TRANSACTION вызывается без параметров, а следовательно с уровнем изоляции транзакции используемой SQL Server по умолчанию. По умолчанию это READ COMMITTED. Так как 1С включает на своих базах данных параметр read_committed_snapshot равным значению 1 (включено), то имеем в итоге READ COMMITTED SNAPSHOT.
SELECT is_read_committed_snapshot_on FR OM sys.databases WHERE name = '1c_database_name';
Таким образом если вынести UPDATE и SELECT в разные транзакции, то от этого ничего не изменится. Если выполнить UPDATE без явного объявления транзакции BEGIN TRANSACTION, то в любом случае эта команда будет выполняться в неявной транзакции с уровнем изоляции по умолчанию.
Короче говоря, таким образом можно уменьшить время выполнения транзакции и удержания эксклюзивных блокировок, установленных командой UPDATE, на время выполнения SELECT. В некоторых случаях это может облегчить жизнь, но не думаю, что это принципиально менят ситуацию с блокировками на таблицах изменений планов обмена.
Таким образом, для решения проблемы с блокировками нам нужно выбирать изменения порциями, то есть передавать в качестве третьего параметра в функцию ВыбратьИзменения() предварительно подготовленный массив объектов, размер которого не приведет к длительным блокировкам и эскалациям.
Разница заключается в использовании временной таблицы для передачи фильтра в виде массива ссылок в метод менеджера планов обмена "ВыбратьИзменения". Это говорит о том, что в каких-то случаях 1С считает, что массив достаточно большой, чтобы начать использовать временную таблицу. Экспериментальным путём удалось выяснить, что количество ссылок в массиве, начиная с которого создаётся временная таблица, равно 129. Создание временной таблицы означает нагрузку на tempdb и дисковую систему сервера СУБД. Это может влиять на продолжительность выполнения всего метода "ВыбратьИзменения" (транзакции СУБД), особенно учитывая тот факт, что в нём выполняются последовательно сначала UPDATE, а только затем SELECT.
Для решения проблем блокировок мой совет: не используйте механизм планов обмена =)