Какие есть типы блокировок при проведении?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие есть типы блокировок при проведении
Блокировки при проведении документов в 1С — это механизм для предотвращения одновременных конфликтующих операций над одними и теми же данными. Это критически важно для обеспечения целостности данных в многопользовательской среде, особенно при работе с документами учёта.
Зачем нужны блокировки
Представьте сценарий:
- Два бухгалтера проводят один и тот же документ одновременно
- Оба читают текущее значение остатка товара (100 шт)
- Оба уменьшают остаток на количество из документа (50 шт каждый)
- В итоге остаток становится 50, вместо 0
Блокировки предотвращают такие ситуации.
Типы блокировок в 1С
1. Блокировка объекта перед проведением
Это основная блокировка, которая предотвращает одновременное проведение одного документа несколькими пользователями.
// Когда пользователь нажимает "Провести"
// 1С автоматически блокирует этот документ
// Другой пользователь не может провести его одновременно
// На уровне системы это выглядит так:
// SELECT FOR UPDATE FROM РегистрСведений WHERE Документ = &ЭтотДокумент
Механизм:
- При начале проведения объект помечается как заблокированный
- Другие пользователи не могут провести этот документ
- После проведения (успешно или с ошибкой) блокировка снимается
2. Блокировка ресурса (Регистры накопления)
Отличается от блокировки объекта. Здесь блокируется не сам документ, а ресурсы, которые он затрагивает.
// Документ: "Отпуск материалов"
// Затрагиваемый ресурс: Остатки товаров по складам
// 1С блокирует строки в регистре, соответствующие:
// Товар = А
// Склад = Основной
// Другой документ, затрагивающий то же самое сочетание,
// будет ждать освобождения блокировки
Пример в коде:
// В обработчике "ПередПроведением"
Процедура ПередПроведением(Отмена, Режим)
// Здесь может быть явная блокировка ресурсов
БлокировкаДанных = Новый БлокировкаДанных();
БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиТоваров");
БлокировкаДанных.Заблокировать();
КонецПроцедуры
3. Блокировка на уровне БД (SELECT FOR UPDATE)
Это низкоуровневая блокировка на уровне SQL. 1С использует её автоматически при проведении.
-- При проведении 1С выполняет что-то похожее на:
SELECT * FROM "_AccRg"
WHERE "Document" = '...'
FOR UPDATE; -- Эта строка означает блокировку
Особенности:
- Работает на уровне СУБД (PostgreSQL, SQL Server, 1С)
- Автоматическая блокировка
- При завершении транзакции автоматически снимается
4. Блокировка таблиц (Table-level lock)
Реже используется, когда операция затрагивает большой объём данных.
// При массовом переоценивании всех товаров
// 1С может заблокировать всю таблицу РегистрНакопления.ОстаткиТоваров
// Это медленнее, но гарантирует консистентность
Практический пример блокировок
Сценарий: Проведение документа "Приходная накладная"
// Модуль документа
Процедура ПередПроведением(Отмена, Режим)
// 1С автоматически добавляет блокировку документа
// Явная блокировка ресурсов (регистров)
БлокировкаДанных = Новый БлокировкаДанных();
БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиТоваров");
БлокировкаДанных.Добавить("РегистрСведений.СтоимостьТоваров");
БлокировкаДанные.Заблокировать();
// Проверка данных
ПроверитьКоличество();
ПроверитьЦены();
КонецПроцедуры
Процедура ПриПроведении(Отмена, Режим)
// Здесь выполняются действия проведения
ОбновитьОстатки();
ОбновитьСтоимость();
// После выполнения ВСЕХ операций блокировка снимается
КонецПроцедуры
Процедура ПослеПроведения(Отмена, Режим)
// Здесь уже нет блокировки
КонецПроцедуры
Объявление блокировок вручную
&НаСервере
Процедура ПровестиДокумент()
// Явное добавление блокировки
БлокировкаДанных = Новый БлокировкаДанных();
// Блокируем конкретный документ
БлокировкаДанных.Добавить("Документ.ПриходнаяНакладная", "Ссылка", Объект.Ссылка);
// Блокируем регистр
БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиТоваров");
// Блокируем справочник
БлокировкаДанных.Добавить("Справочник.Номенклатура");
БлокировкаДанных.Заблокировать();
// Теперь выполняем критичные операции
Попытка
Объект.Провести();
Исключение
// Блокировка автоматически снимается
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Параметры блокировки
// Можно указать режим ожидания
БлокировкаДанных = Новый БлокировкаДанных();
БлокировкаДанных.Добавить("Справочник.Товары");
// Режим 1: Ждать доступности (по умолчанию)
БлокировкаДанных.Заблокировать();
// Режим 2: С тайм-аутом
Попытка
БлокировкаДанных.Заблокировать();
Исключение
// Если не получилось заблокировать за время тайм-аута
Сообщение("Данные заблокированы другим пользователем");
КонецПопытки
Проблемы и их решение
Проблема 1: Deadlock (взаимная блокировка)
Когда процесс A ждёт ресурс, заблокированный процессом B, а процесс B ждёт ресурс, заблокированный процессом A.
// НЕПРАВИЛЬНО - может привести к deadlock
// Процесс 1
БлокировкаДанных.Добавить("Справочник.Товары");
БлокировкаДанных.Добавить("Справочник.Склады");
БлокировкаДанных.Заблокировать();
// Процесс 2 (одновременно)
БлокировкаДанных.Добавить("Справочник.Склады");
БлокировкаДанных.Добавить("Справочник.Товары");
БлокировкаДанных.Заблокировать(); // DEADLOCK!
// ПРАВИЛЬНО - всегда блокируем в одном порядке
БлокировкаДанных.Добавить("Справочник.Склады"); // Сначала Склады
БлокировкаДанных.Добавить("Справочник.Товары"); // Потом Товары
БлокировкаДанных.Заблокировать();
Проблема 2: Долгая блокировка
Если процесс удерживает блокировку слишком долго, другие пользователи ждут.
// НЕПРАВИЛЬНО - блокировка удерживается долго
БлокировкаДанных = Новый БлокировкаДанных();
БлокировкаДанных.Добавить("РегистрНакопления.Остатки");
БлокировкаДанных.Заблокировать();
Для каждого Товар Из ПолучитьВсеТовары() Цикл
ОбработатьТовар(Товар); // Долгая операция со схватом блокировки
КонецЦикла;
// ПРАВИЛЬНО - блокировка только для критичной части
Для каждого Товар Из ПолучитьВсеТовары() Цикл
// Подготовка без блокировки
Данные = ПодготовитьДанные(Товар);
// Только критичная часть
БлокировкаДанных = Новый БлокировкаДанных();
БлокировкаДанных.Добавить("РегистрНакопления.Остатки");
БлокировкаДанных.Заблокировать();
ОбновитьОстаток(Товар, Данные);
// Блокировка автоматически снимается
КонецЦикла;
Практические рекомендации
- Блокируй только необходимое — не блокируй весь регистр, если можно заблокировать конкретную партию
- Минимизируй время блокировки — выполняй все вычисления до блокировки
- Единообразный порядок — всегда блокируй ресурсы в одном порядке для предотвращения deadlock'а
- Логирование конфликтов — отслеживай, где возникают блокировки
- Тестирование нагрузки — проверяй поведение системы при одновременных операциях
Правильное понимание и использование блокировок — это залог стабильной и надёжной работы учётных систем на 1С, особенно в многопользовательской среде.