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

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

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

В наличии

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

Категория:

Описание

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

Тестовый стенд: режим управления блокировками управляемый, версия платформы 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. переделать объектное чтение на чтение через запросы (повторение ошибки исключено)

 

has been added to your cart:
Оформление заказа