Разбор причины ошибки "Нарушение целостности чтения объекта базы данных из-за параллельного изменения объекта другим сеансом"

25.06.21

База данных - Технологический журнал

При нагруженной работе начали возникать ошибки чтения из-за параллельного изменения. Здесь приводится расследование причин проблемы.

О стенде и инструментах

Тестовый стенд: режим управления блокировками управляемый, версия платформы 8.3.12.

Для расследования проблемы использовался технологический журнал (далее по тексту ТЖ).
Более подробно о нем написано написано в публикациях Рецепты приготовления технологического журнала и Описание почти всех событий технологического журнала.

 

Описание ошибки в ЖР

Расследуемая ошибка в журнале регистрации выглядит так:

 

Случай 1 (объектное чтение ПолучитьОбъект())

Воспроизведение

Для воспроизведения проблемы создадим множество потоков на запись следующим кодом

Процедура ЗапуститьФоновыеЗадания(Кнопка)
	
	// Обработка сделана для расследования ошибки:
	// Нарушение целостности чтения объекта базы данных из-за параллельного изменения объекта другим сеансом
	
	МассивПараметров = Новый Массив;
	МассивПараметров.Добавить(Документ);
	МассивПараметров.Добавить(1);
	
	Для Инд = 1 по 100 Цикл
		
		ФоновыеЗадания.Выполнить("Привилегированный.Записать", МассивПараметров, "КлючЗаписать " + Инд);
		ФоновыеЗадания.Выполнить("Привилегированный.Записать", МассивПараметров, "КлючЗаписатьДублирующий " + Инд);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура Записать(Документ, Значение) Экспорт
	
	ДокументОбъект = Документ.ПолучитьОбъект();
	ДокументОбъект.Реквизит = Значение;
	ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
	
КонецПроцедуры

Расследование

Посмотрим на события в ТЖ:

 

Видим последовательность действий по документу ID=282:ae5600505699b66311e9899bd8fdecc8

  1. Наложения неявной блокировки платформой при записи (07:16.164118 TLOCK)
  2. Обновление в СУБД данных документа (07:19.321016 SDBL ... 'UPDATE ...')
  3. Фиксация транзакции вместе с этими изменениями (07:20 SDBL)
  4. Объектное чтение во время фиксации данных объекта (07:20.430016 SDBL, обращаем внимание на чтение версии по документу ID=282:ae5600505699b66311e9899bd8fdecc8)
  5. Ошибку чтения из-за параллельного изменения (07:20.430017 EXCP)

Исправление ошибки

Избежать ошибки можно организовав очередь к документу наложив явную управляемую блокировку перед записью документа

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

В ТЖ будет видно 2 исхода события

1. Успешное наложение блокировки и ожидание 2 потоком пока 1 отработает

2. Неудачная попытка блокировки и откат транзакции

 

Случай 2 (объектное чтение Ссылка.Товары.НайтиСтроки())

Воспроизведение

Рассмотрим аналогичный случай при чтении табличной части документа


Процедура ЗапуститьФоновыеЗадания(Кнопка)
	
	// Обработка сделана для расследования ошибки:
	// Нарушение целостности чтения объекта базы данных из-за параллельного изменения объекта другим сеансом
	
	Склад = Справочники.Склады.НайтиПоКоду("КодСклада");
	
	МассивПараметровЗаписи = Новый Массив;
	МассивПараметровЗаписи.Добавить(Документ);
	МассивПараметровЗаписи.Добавить(1);
	
	МассивПараметровЧтения = Новый Массив;
	МассивПараметровЧтения.Добавить(Документ);
	МассивПараметровЧтения.Добавить(Склад);
	
	Для Инд = 1 по 100 Цикл
		
		ФоновыеЗадания.Выполнить("Привилегированный.Записать", МассивПараметровЗаписи, "КлючЗаписать " + Инд);
		ФоновыеЗадания.Выполнить("Привилегированный.Прочитать", МассивПараметровЧтения, "КлючПрочитать " + Инд);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура Записать(Ссылка, Значение) Экспорт
	
	ДокументОбъект = Ссылка.ПолучитьОбъект();
	ДокументОбъект.Значение= Значение;
	ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
	
КонецПроцедуры

Процедура Прочитать(Ссылка, Склад) Экспорт
	
	Ссылка.Товары.НайтиСтроки(Новый Структура("Склад", Склад));
	
КонецПроцедуры

Расследование

Посмотрим на события в ТЖ:

Видим последовательность по документу ID=282:ae5600505699b66311e9899bd8fdecc8

  1. Наложения неявной блокировки платформой при записи (04:57.680428 TLOCK)
  2. Обновление в СУБД данных документа (04:57/996003 SDBL ... 'UPDATE ...')
  3. Фиксация транзакции вместе с этими изменениями (05:02 SDBL)
  4. Объектное чтение во время фиксации данных объекта (05:02.528150 SDBL, обращаем внимание на чтение версии по документу ID=282:ae5600505699b66311e9899bd8fdecc8)
  5. Ошибку чтения из-за параллельного изменения (05:02.528151)

 

Исправление ошибки

Избежать ошибки можно наложив явную управляемую блокировку перед записью документа или заменив объектное чтение чтением через запросы.

В ТЖ видно чтение через запросы и отсутствие ошибок

Заключение:

Ошибка связана с объектным чтением в момент принятия изменений платформой.
В зависимости от причины ошибки возможны два пути решения:

  1. организовать очередь используя управляемую блокировку (возможно повторение ошибки при доработках)
  2. переделать объектное чтение на чтение через запросы (повторение ошибки исключено)

 

См. также

HighLoad оптимизация Рефакторинг и качество кода Технологический журнал Программист Платформа 1С v8.3 Россия Бесплатно (free)

Технологии бегут вперёд, но боль производительности 1С остаётся вечной: инфраструктура, код или настройки? Пока ИИ не научился чинить всё «на лету», мы автоматизировали ключевое — диагностику. Читайте статью — показываем, как превратить хаос диагностики в понятные графики и цифры. Спойлер: это работает даже если ваша 1С — «чёрный ящик» на старом железе.

19.03.2025    2818    EFSOL_oblako    9    

8

Технологический журнал Механизмы платформы 1С Запросы Программист Запросы Бесплатно (free)

Существуют различные методики и инструменты просмотра запроса 1С в PostgreSQL. В этой статье мы разберём подробнее метод анализа запроса 1С на стороне PostgreSQL с помощью технологического журнала платформы 1С и команд в терминале Ubuntu.

04.03.2025    1127    user593895_gurov-boris-spb    6    

5

HighLoad оптимизация Технологический журнал Системный администратор Программист Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    6956    ivanov660    13    

59

Технологический журнал Мониторинг Системный администратор Программист Абонемент ($m)

Как легко и быстро с помощью специализированных решений собирать, парсить и передавать логи и метрики.

1 стартмани

15.11.2023    2228    8    AlexSTAL    0    

8

Мониторинг Журнал регистрации Технологический журнал Системный администратор Программист Абонемент ($m)

Как легко и быстро с помощью специализированных решений собирать, парсить и передавать логи и метрики.

1 стартмани

13.11.2023    5937    11    AlexSTAL    0    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. alexeyo51 02.11.22 12:01 Сейчас в теме
Встретился случай, когда такая ошибка возникает без записи объекта в другом сеансе, а при последовательной записи в рамках одного сеанса.
Более того ошибка - при записи набора записей с уникальным отбором (движение для нового документа).
2. pashamak 354 02.11.22 12:22 Сейчас в теме
(1) Интересно посмотреть на пример. Может срабатывает отложенное проведение в ФЗ которое остается без внимания.
Оставьте свое сообщение