1
0
mirror of https://github.com/ones-devguide/dev-rules.git synced 2026-04-24 03:33:20 +02:00
Files
dev-rules/docs/theory/data_blocking.md
T
2025-12-19 20:57:49 +07:00

31 KiB

sidebar_position, sidebar_label, title
sidebar_position sidebar_label title
6 Блокировки Блокировки

🚀 Полное руководство по блокировкам

📋 Содержание

  1. Основные понятия и назначение блокировок
  2. Типы блокировок в 1С
  3. Объектные блокировки
  4. Транзакционные блокировки: режимы и уровни изоляции
  5. Работа с блокировками из кода
  6. Ответственное чтение данных
  7. Оптимизация и практические рекомендации
  8. Механизмы контроля остатков в типовых конфигурациях
  9. Частые проблемы и их решения
  10. Ответы на вопросы

🎯 1. Основные понятия и назначение блокировок

Что такое блокировка?

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

Проблемы, которые решают блокировки:

  1. Потерянное изменение — когда изменения одной транзакции перезаписываются другой
  2. "Грязное" чтение — чтение незафиксированных данных
  3. Неповторяемое чтение — разные результаты при повторном чтении тех же данных
  4. Чтение фантомов — появление новых данных между чтениями (актуально для необъектных сущностей, например, регистры сведений и накопления)

Простой аналог:

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

🏗️ 2. Типы блокировок в 1С

1. Объектные блокировки (для работы с объектами: справочники, документы)

  • 1.1. Пессимистические блокировки
    • Явные (через метод Заблокировать() или ЗаблокироватьДанныеДляРедактирования())
    • Неявные (в форме) (автоматически при редактировании в форме)
  • 1.2. Оптимистические блокировки (проверяют версию при записи)

2. Транзакционные блокировки (для работы с данными в транзакциях)

  • 2.1. Автоматические блокировки (управляются СУБД, используются высокие уровни изоляции)
  • 2.2. Управляемые блокировки (управляются разработчиком через 1С, используются низкие уровни изоляции)
    • Явные (создаются через объект БлокировкаДанных)
    • Неявные (устанавливаются платформой автоматически)

Краткая характеристика:

  • Объектные блокировки: Не позволяют интерактивно изменить двум пользователям один объект (элемент справочника или документ)
  • Транзакционные блокировки: Позволяют программно оперировать актуальными данными при выполнении движений по регистрам

👤 3. Объектные блокировки

3.1. Пессимистическая блокировка

Назначение: Запрещает изменение объекта другими сеансами или данным сеансом до снятия блокировки.

Как работает:

  • Автоматически устанавливается при редактировании объекта в форме
  • Вручную можно использовать через Заблокировать() или ЗаблокироватьДанныеДляРедактирования()

Важно: Факт блокировки не мешает изменению объекта — для защиты нужно всегда пытаться заблокировать объект перед изменением.

Пример кода:

ФайлОбъект = ДанныеФайла.Ссылка.ПолучитьОбъект();
Попытка
    ФайлОбъект.Заблокировать(); 
    // Изменяем объект
    ФайлОбъект.Записать();
Исключение
    // Обработка ошибки блокировки
КонецПопытки;

3.2. Оптимистическая блокировка

Назначение: Проверяет, не изменился ли объект с момента его чтения.

Принцип работы:

  • При вызове ПолучитьОбъект() платформа считывает версию данных объекта (ВерсияДанных)
  • Если другой сеанс параллельно изменит и запишет этот же объект, его версия изменится
  • При попытке записи объекта из первого сеанса происходит сравнение версий
  • Если версии не совпадают — возникает ошибка "Нарушение целостности чтения объекта базы данных из-за параллельного изменения объекта другим сеансом"

🔄 4. Транзакционные блокировки: режимы и уровни изоляции

Уровень изоляции транзакций — это параметр СУБД, который определяет степень защиты данных от конфликтов при одновременной работе нескольких транзакций. Он представляет собой компромисс между:

  • Целостностью данных (предсказуемость, непротиворечивость)
  • Параллельностью работы (скорость, производительность)

4.1. Два режима работы

Аспект Автоматический режим Управляемый режим
Уровень изоляции СУБД Repeatable Read или Serializable Read Committed
Управление блокировками Система полагается на механизмы СУБД Разработчик сам управляет блокировками
Производительность Ниже (избыточные блокировки) Выше (точные блокировки)
Рекомендация Для обратной совместимости Для современных конфигураций (рекомендуется)

4.2. Уровни изоляции транзакций в СУБД

Сравнение уровней изоляции:

Проблема / Уровень READ UNCOMMITTED READ COMMITTED REPEATABLE READ SERIALIZABLE
Грязное чтение Возможно Запрещено Запрещено Запрещено
Неповторяемое чтение Возможно Возможно Запрещено Запрещено
Фантомы Возможно Возможно Возможно Запрещено
Параллельность Высокая Средняя Низкая Очень низкая

Read Committed Snapshot (RCSI): Режим версионирования, поддерживается в PostgreSQL, Oracle и MS SQL (с 8.3). Нет ожиданий на блокировках при чтении т.к если другая транзакция пишет данные, ваш запрос не ждет, а читает "старый снимок" данных, которые были до начала записи. Рекомендуется включать для MS SQL в управляемом режиме.

📊 Сравнение Read Committed vs Read Committed Snapshot
Критерий Read Committed Read Committed Snapshot
🛡️ Проблемы, которые решает Только "грязное чтение" "Грязное чтение" + ожидания на блокировках
📖 Как работает чтение Читает последние зафиксированные данные Читает "старый снимок" данных на момент начала запроса
Поведение при конфликте Если данные пишутся другой транзакцией → ждет (блокируется) Если данные пишутся другой транзакцией → не ждет, читает предыдущую версию
📈 Параллельность Средняя (чтение может блокироваться на запись) Высокая (чтение и запись не блокируют друг друга)
💾 Использование памяти Низкое (не хранит старые версии) Высокое (хранит старые версии строк в tempdb до конца транзакции)
⚙️ Включение в MS SQL Уровень по умолчанию Нужно включать отдельно: ALTER DATABASE SET READ_COMMITTED_SNAPSHOT ON

Простая аналогия:

Read Committed Read Committed Snapshot
Библиотека с одной книгой: Читатель ждет, пока другой читатель закончит писать заметки на полях. Библиотека с ксероксом: Читатель сразу получает копию книги в том виде, в котором она была до начала написания заметок.

4.3. Настройка режима в конфигурации

Свойство конфигурации "Режим управления блокировкой данных":

  • Автоматический — все объекты в автоматическом режиме
  • Управляемый — все объекты в управляемом режиме (по умолчанию для новой конфигурации)
  • Автоматический и управляемый — объекты работают в режиме, указанном в их свойствах

Важно: Режим явной транзакции определяется параметром РежимБлокировок метода НачатьТранзакцию(), а не свойством объекта.


💻 5. Работа с блокировками из кода

5.1. Объект БлокировкаДанных — основной инструмент

// Пример установки исключительной блокировки
Блокировка = Новый БлокировкаДанных;
Элемент = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");
Элемент.УстановитьЗначение("Склад", Склад);
Элемент.Режим = РежимБлокировкиДанных.Исключительный; // По умолчанию уже Исключительный
Блокировка.Заблокировать();

5.2. Режимы управляемых блокировок

Таблица совместимости:

Разделяемая Исключительная
Разделяемая
Исключительная

Когда какой режим использовать:

  • Разделяемый: Данные нельзя изменить до конца транзакции (другие могут читать)
  • Исключительный: Данные нельзя ни изменить, ни прочитать с разделяемой блокировкой

5.3. Особенности чтения разных объектов

Сравнение блокировок при чтении в 8.2 и 8.3:

Аспект / Платформа 1С:Предприятие 8.2 (и 8.3 в режиме совместимости) 1С:Предприятие 8.3 (без режима совместимости) Рекомендация
Запрос.Выполнить() Ставится S-блокировка (разделяемая) в СУБД Блокировка на чтение отсутствует 8.3 выигрывает в параллельности
НаборЗаписей.Прочитать() Управляемая разделяемая блокировка до конца транзакции Аналогично 8.2 Для чистого чтения используйте Запрос!
Объектное чтение (справочники, документы) Управляемые блокировки не устанавливаются Аналогично 8.2 Для чтения безопаснее, чем НаборЗаписей

📌 Ключевая проблема: НаборЗаписей.Прочитать() всегда устанавливает управляемую разделяемую блокировку, которая держится до конца транзакции!


📖 6. Ответственное чтение данных

6.1. Что такое ответственное чтение?

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

Примеры:

  • Чтение остатков при проведении документа для формирования движений
  • Получение данных для последующей целостной передачи в другую систему
  • Групповая обработка в обновлениях ИБ

6.2. Как обеспечить ответственное чтение?

Неправильный подход (риск потери данных):

КоличествоЗаметок = ЗапросНаЧтениеЗаметок().Выполнить();
// МЕЖДУ ЧТЕНИЕМ И ЗАПИСЬЮ ДРУГОЙ СЕАНС МОЖЕТ ИЗМЕНИТЬ ДАННЫЕ!
ЗаписатьНовуюЗаметку(КоличествоЗаметок + 1);

Правильный подход (с блокировками):

НачатьТранзакцию();
Попытка
    // 1. Блокируем данные ПЕРЕД чтением
    Блокировка = Новый БлокировкаДанных;
    Элемент = Блокировка.Добавить("РегистрСведений.ЗаметкиПоПредмету");
    Элемент.УстановитьЗначение("Предмет", ПредметЗаметок);
    Элемент.Режим = РежимБлокировкиДанных.Исключительный;
    Блокировка.Заблокировать();

    // 2. Читаем и изменяем данные
    КоличествоЗаметок = ЗапросНаЧтениеЗаметок().Выполнить();
    ЗаписатьНовуюЗаметку(КоличествоЗаметок + 1);

    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    // Обработка ошибки
КонецПопытки;

6.3. Когда ответственное чтение НЕ требуется?

  1. Получение данных для отображения: Динамические списки, поиск, отчеты
  2. Работа с условно-постоянными данными: Константы, учетная политика
  3. Монопольный режим: Обновление базы, первоначальное заполнение
  4. Персональные/уникальные данные: Данные в разрезе пользователей, мобильное приложение

6.4. Выбор типа блокировки

Основные правила:

  1. Читаете и потом изменяете те же данныеИсключительная блокировка
  2. Читаете данные (чтобы они не менялись), но изменяете другиеРазделяемая блокировка на читаемые + исключительная на изменяемые
  3. Только чтение без последующих измененийБлокировка не нужна

7. Оптимизация и практические рекомендации

7.1. Ключевые принципы оптимизации

1. Минимизация времени удержания блокировок

Плохо (долгая блокировка):

НачатьТранзакцию();
Блокировка(); // Ранняя блокировка
// ... долгие расчеты (10 секунд) ...
Записать();
ЗафиксироватьТранзакцию();

Хорошо (короткая блокировка):

// Расчеты БЕЗ транзакции (10 секунд)
НачатьТранзакцию();
Блокировка(); // Блокировка в конце
Записать();
ЗафиксироватьТранзакцию(); // Блокировка всего 0.1 секунды

2. Правильный выбор метода доступа к данным

  • Для чтения: Всегда используйте Запрос вместо НаборЗаписей.Прочитать()
  • Для изменения: Используйте объектную модель с блокировками

3. Использование разделителя итогов

Включите галочку "Разрешить разделение итогов" для регистров без контроля остатков. Это позволяет параллельно обновлять итоги по одному набору измерений.

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

Что это: Когда блокируется не строка, а вся таблица или пространство.

Пороги эскалации:

  • MS SQL Server: >5 000 блокировок одной инструкцией
  • 1С:Предприятие 8.2: ~20 000 блокировок на одно пространство
  • 1С:Предприятие 8.3: ~100 000 блокировок на одно пространство

Решение: Делите большие операции на пакеты (по 1000-2000 записей).

7.3. Рекомендации по оптимизации

  1. Перейти на управляемый режим блокировок
  2. Включить RCSI (Read Committed Snapshot) для MS SQL
  3. Включить разделитель итогов для регистров без контроля остатков
  4. Использовать Запрос вместо НаборЗаписей.Прочитать() для чтения
  5. Делать транзакции короткими
  6. Использовать многопоточность для массовых операций
  7. Мониторить блокировки специальными инструментами

🏢 8. Механизмы контроля остатков в типовых конфигурациях

8.1. Два механизма контроля остатков

Аспект Старый механизм (OLD) Новый механизм (NEW)
Принцип работы 1. Контроль остатков (запрос) 2. Запись движений 1. Запись движений 2. Проверка на отрицательные остатки
Использование Бухгалтерия 3.0, некоторые алгоритмы УТ 11, КА 2, ЕРП 2 УТ 11, КА 2, ЕРП 2 (основной механизм)
Преимущества 1. Выше скорость проведения 2. Нет перезаписи пустых наборов 3. Нет необходимости в предварительной блокировке
Недостатки Требует блокировки данных при чтении (снижает параллельность) Если для проведения нужны данные из регистров, блокировка при чтении все равно требуется

Вывод: Используйте новый механизм (NEW), если проведение документа не требует предварительных запросов к данным.

8.2. Стратегии блокировок для разных режимов

Для управляемого режима с NEW механизмом:

// Ключевая настройка для регистров с разделением итогов!
НаборЗаписей.БлокироватьДляИзменения = Истина;

Эта настройка временно отключает разделение итогов для данного набора, предотвращая конфликты. Устанавливается обычно перед записью.

🚨 9. Частые проблемы и их решения

9.1. Взаимоблокировки (Deadlock)

Симптом: Две транзакции ждут друг друга.

Причины:

  • Неоптимальный порядок блокировок
  • Длительные транзакции
  • Отсутствие индексов

Решение:

  • Устанавливать блокировки в одинаковом порядке
  • Делать транзакции короткими
  • Использовать правильные индексы

9.2. Ожидания на блокировках

Причины:

  • НаборЗаписей.Прочитать() в транзакции
  • Длительные запросы со сканированием
  • Отсутствие разделителя итогов в регистрах

Решение:

  • Заменять НаборЗаписей на Запросы
  • Оптимизировать запросы
  • Включать разделитель итогов

9.3. Сводная таблица решений

Проблема Суть Решение
Грязное чтение Читаем незафиксированные данные S-блокировка на время чтения
Потеря изменений Перезапись изменений другого процесса X-блокировка на всю транзакцию
Неповторяемое чтение Данные меняются между чтениями в одной транзакции S-блокировка на всю транзакцию
Чтение фантомов Появление новых строк между запросами Блокировка диапазона

10. Ответы на ключевые вопросы

Базовые вопросы:

  1. Какие типы блокировок существуют в 1С? → Объектные и транзакционные
  2. В чем разница между пессимистической и оптимистической блокировкой? → Пессимистическая блокирует сразу, оптимистическая проверяет при записи
  3. Что такое ответственное чтение? → Чтение, после которого происходят изменения или принимаются решения

Практические вопросы:

  1. Когда нужно использовать ЗаблокироватьДанныеДляРедактирования()? → Перед изменением объекта из кода
  2. Почему НаборЗаписей.Прочитать() может вызывать проблемы? → Ставит управляемую блокировку до конца транзакции
  3. Как перевести конфигурацию на управляемые блокировки? → Установить режим "Управляемый" и настроить блокировки в коде

Глубинные вопросы:

  1. В чем разница между автоматическим и управляемым режимом? → Автоматический использует высокие уровни изоляции СУБД, управляемый — низкие с ручным управлением
  2. Как избежать взаимоблокировок при проведении документов? → Правильный порядок блокировок, короткие транзакции, использование БлокироватьДляИзменения
  3. Что такое эскалация блокировок и как с ней бороться? → Укрупнение блокировки при большом количестве; делить операции на пакеты

Вопросы на понимание:

  1. Когда НЕ нужно устанавливать блокировки? → При чтении для отображения, работе с константами, в монопольном режиме
  2. Какой уровень изоляции используется в управляемом режиме и почему?Read Committed для большей параллельности
  3. В чем преимущество нового механизма контроля остатков (NEW)? → Не требует предварительной блокировки, выше скорость

🎓 Ключевые выводы

  1. Блокировки — обязательный механизм для обеспечения целостности данных в многопользовательской среде
  2. Используйте управляемый режим для современных конфигураций — он дает большую гибкость и производительность
  3. Всегда блокируйте данные перед изменением из кода, используя Заблокировать() или БлокировкаДанных
  4. Избегайте НаборЗаписей.Прочитать() для чтения — используйте Запросы
  5. Делайте транзакции короткими — выносите расчеты за пределы транзакции
  6. Понимайте разницу между механизмами контроля остатков OLD и NEW
  7. Используйте инструменты мониторинга для анализа блокировок в реальном времени
  8. Помните об эскалации при работе с большими объемами данных в

📚 Материалы