Добрый день!
Столкнулся с проблемой конфликта блокировок на мобильной платформе.
Версии мобильной платформы: 8.3.10.51, 8.3.10.62. Android 6.0
В мобильной конфигурации используется план обмена. Обмен с центральной базой через HTTP-сервис.
Каждые 2-3 секунды получаются текущие координаты GPS и записываются в регистр сведений.
Получение координат реализовано через подписку СредстваГеопозиционирования.ПодключитьОбработчикИзмененияМестоположения.
Каждые 10 секунд выполяется фоновое задание, в котором происходит обмен.
Так как в обмене "мобильный -> сервер" участвуют изображения по 5mb, то чтобы не блокировать работу на всё время отправки сообщения, была реализована выборка изменений в очередь сообщений, и затем уже отдельная отправка, не блокирующая таблицы изменений.
С очень частой периодчностью (раз в несколько минут) появляется сообщение о конфликте блокировок.
В основном сеансе при
а в фоновом задании при
Сервер и блокировки на стороне сервера из за множества одновременных сеансов по обмену - тут вообще не причем.
Авторегистрация по регистру отключена. Регистрация происходит путем
в подписке на событие ПередЗаписью
В нескольких словах, в двух параллельных сеансах с разным интервалом происходит обращение к таблице изменений. Понятно что эти интервалы время от времени пересекаются. Согласно логике, в этом случае один сеанс должен будет ждать другой какое-то непродолжительное время, а затем продолжить работу.
А на деле происходит дед-лок, вроде-бы, на ровном месте.
Помогите понять куда копать, как получить больше информации о причинах, как устранить... Спасибо.
Столкнулся с проблемой конфликта блокировок на мобильной платформе.
Версии мобильной платформы: 8.3.10.51, 8.3.10.62. Android 6.0
В мобильной конфигурации используется план обмена. Обмен с центральной базой через HTTP-сервис.
Каждые 2-3 секунды получаются текущие координаты GPS и записываются в регистр сведений.
Получение координат реализовано через подписку СредстваГеопозиционирования.ПодключитьОбработчикИзмененияМестоположения.
Процедура ЗаписатьМестоположениеВИсторию(Местоположение) Экспорт
ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь;
КоординатыМестоположения = Местоположение.Координаты;
НаборЗаписей = РегистрыСведений.ИсторияМестоположения.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Период.Установить(Местоположение.Дата);
НаборЗаписей.Отбор.Пользователь.Установить(ТекущийПользователь);
Запись = НаборЗаписей.Добавить();
Запись.Период = Местоположение.Дата;
Запись.Пользователь = ТекущийПользователь;
Запись.Высота = КоординатыМестоположения.Высота;
Запись.Долгота = КоординатыМестоположения.Долгота;
Запись.Широта = КоординатыМестоположения.Широта;
Запись.Направление = Местоположение.Направление;
Запись.Скорость = Местоположение.Скорость;
Запись.ВертикальнаяТочность = Местоположение.ВертикальнаяТочность;
Запись.ГоризонтальнаяТочность = Местоположение.ГоризонтальнаяТочность;
НаборЗаписей.Записать();
КонецПроцедуры
ПоказатьКаждые 10 секунд выполяется фоновое задание, в котором происходит обмен.
Так как в обмене "мобильный -> сервер" участвуют изображения по 5mb, то чтобы не блокировать работу на всё время отправки сообщения, была реализована выборка изменений в очередь сообщений, и затем уже отдельная отправка, не блокирующая таблицы изменений.
Процедура СформироватьПакетыОбменаИДобавитьВОчередь(Узел) Экспорт
Попытка
НачатьТранзакцию();
МассивОбъектов = Новый Массив;
Выборка = ПланыОбмена.ВыбратьИзменения(Узел, 0);
Пока Выборка.Следующий() Цикл
Объект = Выборка.Получить();
МассивОбъектов.Добавить(Объект);
КонецЦикла;
ПорцияОбъектов = Новый Массив;
Для Сч = 1 По МассивОбъектов.Количество() Цикл
Объект = МассивОбъектов[Сч - 1];
ПорцияОбъектов.Добавить(Объект);
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, ?(ТипЗнч(Объект) = Тип("Структура"), Объект.Ссылка, Объект));
Если Сч % 50 = 0 И ПорцияОбъектов.Количество() > 0 Тогда
ТекстСообщения = РаботаСJSON.СериализоватьВJSON(ПорцияОбъектов);
ДобавитьСообщениеОбменаВОчередь(Узел, ТекстСообщения);
ПорцияОбъектов = Новый Массив;
КонецЕсли;
КонецЦикла;
Если ПорцияОбъектов.Количество() > 0 Тогда
ТекстСообщения = РаботаСJSON.СериализоватьВJSON(ПорцияОбъектов);
ДобавитьСообщениеОбменаВОчередь(Узел, ТекстСообщения);
ПорцияОбъектов = Новый Массив;
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
ПоказатьС очень частой периодчностью (раз в несколько минут) появляется сообщение о конфликте блокировок.
В основном сеансе при
НаборЗаписей.Записать();
Конфликт блокировок при выполнении транзакции:
Не удалось заблокировать таблицу '_InfoRgChngR275'
а в фоновом задании при
Объект = Выборка.Получить();
Ошибка при вызове метода контекста (Получить):
Конфликт блокировок при выполнении транзакции: <и тут пусто, нет подробностей>
Сервер и блокировки на стороне сервера из за множества одновременных сеансов по обмену - тут вообще не причем.
Авторегистрация по регистру отключена. Регистрация происходит путем
Объект.ОбменДанными.Получатели.Добавить(УзелЦБ);
в подписке на событие ПередЗаписью
В нескольких словах, в двух параллельных сеансах с разным интервалом происходит обращение к таблице изменений. Понятно что эти интервалы время от времени пересекаются. Согласно логике, в этом случае один сеанс должен будет ждать другой какое-то непродолжительное время, а затем продолжить работу.
А на деле происходит дед-лок, вроде-бы, на ровном месте.
Помогите понять куда копать, как получить больше информации о причинах, как устранить... Спасибо.
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1)
Ну так блокируйте данные, блокировки то управляемые, ожидание и будет.
Согласно логике, в этом случае один сеанс должен будет ждать другой какое-то непродолжительное время, а затем продолжить работу.
А на деле происходит дед-лок, вроде-бы, на ровном месте.
А на деле происходит дед-лок, вроде-бы, на ровном месте.
Ну так блокируйте данные, блокировки то управляемые, ожидание и будет.
(2)
Так должно работать, но это же ненормальный костыль. Да и "ПланыОбмена.ВыбратьИзменения" и так должен блокировать всё что нужно.
Ну так блокируйте данные, блокировки то управляемые, ожидание и будет.
Попытка
НачатьТранзакцию();
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ИсторияМестоположения");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
// на конкретном устройстве данных по разным изменениям нет, поэтому отбор пропускаем.
Блокировка.Заблокировать();
МассивОбъектов = Новый Массив;
Выборка = ПланыОбмена.ВыбратьИзменения(Узел, 0);
...
ПоказатьТак должно работать, но это же ненормальный костыль. Да и "ПланыОбмена.ВыбратьИзменения" и так должен блокировать всё что нужно.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот