Что такое блокировки в 1С и как они устроены?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Назначение и проблема
Блокировки (Locks) — это механизм 1С для синхронизации доступа к данным в многопользовательской среде. Они предотвращают race conditions и несогласованность данных, когда несколько пользователей или процессов одновременно работают с одним и тем же объектом.
Проблема без блокировок:
// Сценарий гонки
Пользователь 1: Прочитал Счёт (остаток = 1000)
Пользователь 2: Прочитал Счёт (остаток = 1000)
Пользователь 1: Спишет 500, Счёт = 500
Пользователь 2: Спишет 300, Счёт = 700 // Ошибка: должно быть 200!
Типы блокировок
1. Блокировка при редактировании объекта
Когда пользователь открывает объект на редактирование, 1С автоматически его блокирует:
// Автоматическая блокировка
Документ = Документы.ПриходТоваров.ПолучитьОбъект(Ссылка);
// Документ заблокирован — другие не смогут его редактировать
Документ.Записать(РежимЗаписи.Проведение);
// Блокировка снята после записи
Как это работает:
- 1С фиксирует в БД кто и когда открыл объект
- Другие пользователи видят "Объект редактируется"
- При попытке редактирования → диалог "Занято"
2. Явная блокировка данных
Используется конструкция НаЧтение() / НаИзменение() для явного захвата ресурсов:
// Блокировка для чтения (shared lock)
БлокировкаДанных = Новый БлокировкаДанных();
БлокировкаДанных.Добавить("РегистрНакопления.ОстаткиТоваров");
БлокировкаДанных.Заблокировать();
ОстатокТовара = ОстаткиТоваров.Получить(СтруктураОтбора);
БлокировкаДанных.Разблокировать();
Уровни блокировки:
- НаЧтение() — shared lock
- НаИзменение() — exclusive lock
Механизм работы
1С использует оптимистичную модель:
// Этап 1: Чтение данных (без блокировки)
Запрос = Новый Запрос("ВЫБРАТЬ Остаток ИЗ ...");
Результат = Запрос.Выполнить();
// Этап 2: Обработка в памяти
ОстатокДо = Результат.Первая().Остаток;
// Этап 3: При изменении — приоритет по времени
ДокОбъект = Документ.ПолучитьОбъект();
// Если другой процесс изменил -> конфликт версий -> ошибка
ДокОбъект.Записать();
При конфликте версий:
Попытка
ДокОбъект.Записать();
Исключение
Сообщение = ИнформацияОбОшибке().Описание;
КонецПопытки;
Deadlock и его избежание
Deadlock — когда два процесса ждут друг друга:
// Процесс 1: Заблокировал Счёт, ждёт Товара
// Процесс 2: Заблокировал Товар, ждёт Счёта
// Результат: полная заморозка
Решение: Блокируй объекты в одинаковом порядке:
БлокировкаДанных = Новый БлокировкаДанных();
// Сначала Счёта, потом Товары (ВСЕГДА в этом порядке)
БлокировкаДанных.Добавить("Справочник.Счета", "Счёт");
БлокировкаДанных.Добавить("Справочник.Номенклатура", "Номенклатура");
БлокировкаДанных.Заблокировать();
Оптимизация
Держи блокировку минимально:
// ❌ Плохо: долгая блокировка
БлокировкаДанных.Заблокировать();
ДорогойРасчёт(); // 10 секунд
БлокировкаДанных.Разблокировать();
// ✅ Хорошо: короткая блокировка
ДорогойРасчёт();
БлокировкаДанных.Заблокировать();
БыстрыеИзменения();
БлокировкаДанных.Разблокировать();
Практический пример
// Безопасный перевод денег между счетами
Попытка
БлокировкаДанных = Новый БлокировкаДанных();
БлокировкаДанных.Добавить("Документ.Перевод", "Ссылка");
БлокировкаДанных.Заблокировать();
Переводы = Переводы.ПолучитьОбъект(Ссылка);
Переводы.Статус = "Обработан";
Переводы.Записать();
БлокировкаДанных.Разблокировать();
Исключение
Сообщение("Перевод уже обработан другим процессом");
КонецПопытки;
Правильное использование блокировок — основа надёжной многопользовательской системы в 1С.