Книга: Настольная книга 1С:Эксперта по технологическим вопросам
Назад: Взаимоблокировка (deadlock)
Дальше: 3.11.Сведения о параллельности операций с данными разных типов

3.10.Эскалация блокировок

Эскалация (укрупнение) блокировок – это повышение гранулярности блокировки (lock granularity, в некоторых источниках – lock level, «уровень блокируемых данных»). Это процесс преобразования многих мелкогранулированных блокировок в меньшее число крупногранулированных блокировок при вероятном увеличении конкуренции параллелизма.

Гранулярность – это объем (уровень в иерархии) ресурсов, на который накладывается блокировка. Упрощенно можно считать, что существуют следующие ресурсы, которые могут блокироваться СУБД:

Не важно, блокировались данные на уровне записей (строк), на уровне диапазона ключа или на уровне страницы. После эскалации они окажутся заблокированы на уровне таблицы, т. е. эскалация всегда происходит до уровня таблицы.

Эскалация происходит, когда система решает, что заблокировать сразу более высокий уровень данных дешевле, чем продолжать набирать большое количество блокировок на нижнем уровне.

Эскалация определяется, например, по наличию в трассировке профайлера SQL Server события Lock:Escalation (в стандартном шаблоне трассировки этого события нет, и его надо добавлять, а находится оно в группе событий Locks), см. главу «Инструкции», раздел .

Перевод блокировки данных на уровень таблицы не позволит другим транзакциям параллельно работать с теми же данными. Она почти всегда избыточна, и это может привести к конфликтам блокировок, поэтому надо понимать, при каких условиях возникает эскалация.

Эксперименты показывали, что в SQL server с установками по умолчанию эскалация блокировки начиналась примерно при 3400–4800 записях в наборе непериодического независимого регистра сведений (точное значение не установлено). В IBM DB2 9.7 она начиналась ровно при 20 000 записях. Платформа «1С:Предприятие» до версии 8.3 производила эскалацию, также начиная с 20 000 записей, а в версии 8.3, по данным с ИТС, она начинается со 100 000 записей в наборе.

Момент, когда это происходит, в SQL server регулируется значением параметра Locks («Блокировки») – SQL Management studio, свойства SQL server, закладка Дополнительно – и зависит от доступной памяти. Также эскалация SQL server может быть отключена. Если отключать ее, то глобально, с помощью флага трассировки SQL 1211, например, выполнив следующий SQL запрос:

DBCC TRACEON (1211, -1)

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

Наличие технической возможности по отключению эскалацию отнюдь не означает, что этим надо пользоваться. СУБД делает эскалацию не от хорошей жизни. Это жест отчаянья. СУБД видит, что пользователи открыли огромные транзакции, и сама она тратит очень много ресурсов. Проблема не в СУБД, а в том, что транзакции захватывают слишком много ресурсов. Лечить надо именно это, а не отключать эскалации.

В идеале транзакция должна быть крайне компактной – работать быстро, данных захватывать мало. Транзакция, которая длится 3 секунды, – это уже подозрительно. Транзакция на 10 секунд просто не должна иметь права на существование.

Включить эскалацию обратно можно, деактивировав флажок 1211:

DBCC TRACEОFF (1211, -1)

На практике можно считать, что при использовании MS SQL Server документ «1С», имеющий свыше 1000 строк в табличной части либо делающий свыше 1000 движений по одному регистру, теоретически может при своем проведении вызывать эскалацию блокировок, поэтому при прочих равных условиях наличие больших документов – это потенциальная проблема параллельности работы. Это не значит, что такие документы нельзя провести. Просто нужно делать это не средствами платформы, а своим кодом – в нескольких относительно небольших транзакциях, обеспечив неделимость (атомарность) операции внешними средствами.

Назад: Взаимоблокировка (deadlock)
Дальше: 3.11.Сведения о параллельности операций с данными разных типов