← Назад к вопросам

Что такое блокировки в 1С и как они устроены?

1.7 Middle🔥 111 комментариев
#Блокировки и транзакции#Стандарты разработки

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Назначение и проблема

Блокировки (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С.

Что такое блокировки в 1С и как они устроены? | PrepBro