Планы обмена. Управляемый режим блокировок

0. 914 13.11.16 19:55 Сейчас в теме
Статья о том, как устроен объект конфигурации 1С:Предприятие 8 "План обмена", в том числе на уровне СУБД SQL Server. Анализируются особенности его использования при управляемом режиме блокировок.

Перейти к публикации

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Evil Beaver 6959 28.11.16 16:14 Сейчас в теме
Я, может быть, не прав, но по-моему, транзакция начинается еще до момента вызова ПередЗаписью. Т.е. в обработчике ПередЗаписью транзакция уже открыта.
2. zhichkin 914 28.11.16 17:35 Сейчас в теме
(1) Вы абсолютно правы! Спасибо за замечание. Поправил.
3. headMade 143 28.11.16 17:42 Сейчас в теме
Посмотрите - вроде часть скринов пропала. Например там где "выполнив код SQL:".
4. zhichkin 914 28.11.16 17:44 Сейчас в теме
(3) Да, есть такое дело. Честно говоря, устал бороться с этим явлением =(
5. spezc 691 29.11.16 12:52 Сейчас в теме
Так как в итоге то? Какое лекарство, когда например 100 узлов решили обменяться информацией с центром?
EMelihoff; +1 Ответить
7. zhichkin 914 04.12.16 16:59 Сейчас в теме
(5) Прошу прощения, но Вы бы не могли уточнить, что конкретно имеется ввиду? Например, я понял вопрос так: есть 100 входящих сообщений обмена для центральной базы. Вероятно это РИБ. Если каждое сообщение имеет по 1 объекту, то я не вижу в этом вообще никакой проблемы ... Дайте, пожалуйста, цифры.
8. zhichkin 914 04.12.16 20:43 Сейчас в теме
(5) Если отвечать на Ваш вопрос глобально, то, при условии, что были исчерпаны все варианты оптимизации планов обмена, нужно использовать альтернативные варианты. Например, можно использовать свою реализацию регистрации изменений. Это как минимум. Некоторые размышления по этому поводу я зафиксировал здесь. Есть и другие публикации по этому поводу. Ссылки на них можно найти в моём профиле.

В ближайшее время я планирую сделать ещё пару публикаций на тему того как можно оптимизировать работу планов обмена. Если проблемы серьёзные и требуется частная консультация, то я готов оказать посильную помощь. Пишите в личку.
11. sommid 11.01.17 18:07 Сейчас в теме
(8)
В ближайшее время я планирую сделать ещё пару публикаций на тему того как можно оптимизировать работу планов обмена

- если не сложно, то отпишитесь в комментариях этой темы. Интересно будет почитать. Спасибо.
6. tormozit 6232 29.11.16 14:57 Сейчас в теме
9. kolya_tlt 24 11.01.17 13:53 Сейчас в теме
Добрый день.
было бы здорово добавить в статью информацию по автоматическому режиму или отличий с управляемым
10. zhichkin 914 11.01.17 15:07 Сейчас в теме
(9) Тут не так много мест где будут отличия. Пожалуй это все те места, где выполняется команда SELECT. Если Вы хорошо понимаете разницу между READ COMMITED (автоматический режим) и READ COMMITED SNAPSHOT (управляемый режим), то без труда поймёте где и какая разница возникает.

Если отвечать упрощённо, то разница между этими двумя режимами такова, что:
1. При чтении данных:
в первом случае мы получаем версию записи после её изменения в другой транзакции. При этом мы ждём её завершения (нас блокируют - мы ждём, чтобы прочитать). А в случае со snapshot, мы получаем версию записи, которая была до начала второй транзакции. При этом мы ничего не ждём и допускаем "грязное чтение".
2. В процессе чтения данных:
в первом случае мы блокируем транзакции, которые желают изменить данные, которые мы читаем (мы блокируем - нас ждут, чтобы изменить). А в случае со snapshot мы никого не блокируем.

Некоторые могут подумать, что в первом случае прочитанные нами данные блокируются до конца транзакции, но это не так. Уточняю: речь идёт о первом случае (автоматический режим блокировок), когда опция read_commited_snapshot на уровне базы данных имеет значение OFF (выключено).
Это зависит от режима изоляции транзакции. В случае с планами обмена используется режим изоляции транзакции SQL Server по умолчанию, а он чаще всего равен READ COMMITED, то есть данные блокируются только на время их чтения.
То есть одна запись блокируется пока она читается в выборку, затем блокировка снимается, делается попытка получить разрешение на чтение следующей записи, устанавливается блокировка чтения и читается следующая запись. И так до тех пор, пока все, попавшие в условие отбора, записи не будут прочитаны.
13. kolya_tlt 24 12.01.17 09:26 Сейчас в теме
(10)
А в случае со snapshot, мы получаем версию записи, которая была до начала второй транзакции. При этом мы ничего не ждём и допускаем "грязное чтение".

хм, где про снэпшот такую информацию пишут ? мне казалось COMMTITED исключает грязное чтение
14. zhichkin 914 12.01.17 14:01 Сейчас в теме
(13) Очень много информации по этим вопросам можно найти в сети Интернет, например:
https://msdn.microsoft.com/ru-ru/library/tcbchxcb(v=vs.110).aspx
https://habrahabr.ru/post/305600/
15. zhichkin 914 12.01.17 14:06 Сейчас в теме
(13) Коротко отвечу всё же:
READ COMMITTED - это уровень изоляции транзакций, как правило, используемый SQL Server.
read_committed_snapshot - это опция уровня базы данных, которая может изменять поведение уровня изоляции READ COMMITTED, принятое по умолчанию. По умолчанию read_committed_snapshot = OFF. Однако при включении управляемого режима блокировок 1С переключает это значение в положение ON. Это меняет поведение уровня изоляции транзакций READ COMMITTED принятое по умолчанию.
1cprogr_nsk; +1 Ответить
16. VVi3ard 50 06.09.17 09:55 Сейчас в теме
Интересная статья, для полноты не хватает описания того как работает платформа при использовании: ЗаписатьИзменения, и особенно в части работы параметра "ЭлементовВТранзакции".
17. EvgeniyEY 15.06.20 18:01 Сейчас в теме
Полезная статья, спасибо.
18. Sirruf 139 28.01.21 11:19 Сейчас в теме
А кто-нибудь задумывался почему ВыбратьИзменения() выполняется в транзакции? Что произойдет (сломается), если гипотетически убрать транзакцию?
19. zhichkin 914 28.01.21 11:58 Сейчас в теме
(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. В некоторых случаях это может облегчить жизнь, но не думаю, что это принципиально менят ситуацию с блокировками на таблицах изменений планов обмена.
20. Sirruf 139 28.01.21 13:41 Сейчас в теме
(19) То есть вы согласны с моим мнением, что транзакция в данном случае избыточна?
22. zhichkin 914 28.01.21 14:21 Сейчас в теме
(20) Да, это очевидно: SELECT нужно убирать из транзакции.
24. Sirruf 139 28.01.21 18:08 Сейчас в теме
(22) Хорошо, попробуем на партнерском форуме написать об этом разработчикам :)
21. Sirruf 139 28.01.21 13:46 Сейчас в теме
Таким образом, для решения проблемы с блокировками нам нужно выбирать изменения порциями, то есть передавать в качестве третьего параметра в функцию ВыбратьИзменения() предварительно подготовленный массив объектов, размер которого не приведет к длительным блокировкам и эскалациям.
23. zhichkin 914 28.01.21 14:26 Сейчас в теме
(21) Косвенно пишу об этом в своей статье "Анализ блокировок СУБД: таблица изменений плана обмена 1С", пункт 4 "Анализ технологического журнала 1С":
Разница заключается в использовании временной таблицы для передачи фильтра в виде массива ссылок в метод менеджера планов обмена "ВыбратьИзменения". Это говорит о том, что в каких-то случаях 1С считает, что массив достаточно большой, чтобы начать использовать временную таблицу. Экспериментальным путём удалось выяснить, что количество ссылок в массиве, начиная с которого создаётся временная таблица, равно 129. Создание временной таблицы означает нагрузку на tempdb и дисковую систему сервера СУБД. Это может влиять на продолжительность выполнения всего метода "ВыбратьИзменения" (транзакции СУБД), особенно учитывая тот факт, что в нём выполняются последовательно сначала UPDATE, а только затем SELECT.

Для решения проблем блокировок мой совет: не используйте механизм планов обмена =)
Оставьте свое сообщение
Вопросы с вознаграждением