ПланыОбмена.ВыбратьИзменения() - в какой момент закрывается транзакция? Как избавиться от конфликтов блокировок?
Добрый день.
Столкнулся с проблемой транзакция при выгрузке больших объемов данных использую механизм планов обмена.
после этой строки блокируется запись всех объектов, входящих в состав текущего плана обмена.
Сама строка выполняется быстро, через консольку смотрю, номера обмена проставлены, но все еще висит транзакция.
В какой момент она закрывается? как ее закрыть принудительно.
Не знаю важно это или нет, вся работа идет в модуле вебсервиса, и транзакция завершается только после того, как отработает полностью весь код обмена.
Получается так:
1 - проставляю номера обмена в зарегистрированных данных в текущем узле - эта операция проходит быстро.
2 - получение измененных с помощью запроса - тоже быстрая операция
3 - выгружаю данные в файл - эта операция длительная и пока она не отработает, в 1С работать не возможно - конфликт блокировок.
Может есть способ проставить НомерСообщения в изменениях не использую ВыбратьИзменения
Столкнулся с проблемой транзакция при выгрузке больших объемов данных использую механизм планов обмена.
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
после этой строки блокируется запись всех объектов, входящих в состав текущего плана обмена.
Сама строка выполняется быстро, через консольку смотрю, номера обмена проставлены, но все еще висит транзакция.
В какой момент она закрывается? как ее закрыть принудительно.
Не знаю важно это или нет, вся работа идет в модуле вебсервиса, и транзакция завершается только после того, как отработает полностью весь код обмена.
Получается так:
1 - проставляю номера обмена в зарегистрированных данных в текущем узле - эта операция проходит быстро.
2 - получение измененных с помощью запроса - тоже быстрая операция
3 - выгружаю данные в файл - эта операция длительная и пока она не отработает, в 1С работать не возможно - конфликт блокировок.
Может есть способ проставить НомерСообщения в изменениях не использую ВыбратьИзменения
Ответы
В избранное
Подписаться на ответы
Сортировка:
Древо развёрнутое
Свернуть все
(1) Транзакция закроется после обхода всей выборки.
избавится от конфликта бликировок можно путем отказа от ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного) совсем, вместо этого делать запрос вида:
избавится от конфликта бликировок можно путем отказа от ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного) совсем, вместо этого делать запрос вида:
Выбрать Ссылка Из Справочник.<ИмяСправочника>.Изменения ГДЕ Узел = &Узел и НомерСообщения = &НомерСообщения
(2) это хорошо, я так и делаю, только проблема в том, что в момент выборки документов и отправки данных, происходит запись объектов, они регистрируются в ПО с номером =0(точнее null)
И если не вызывать ПланыОбмена.ВыбратьИзменения, то этот самый номер сообщения не изменится для объектов, которые я уже выгрузил. Затем от принимающей стороны приходит ответ с номером принятого сообщения и должен удалить регистрацию объхектов с необходимым номером. И как мне это сделать?
И если не вызывать ПланыОбмена.ВыбратьИзменения, то этот самый номер сообщения не изменится для объектов, которые я уже выгрузил. Затем от принимающей стороны приходит ответ с номером принятого сообщения и должен удалить регистрацию объхектов с необходимым номером. И как мне это сделать?
Вот кусок из справки по ВыбратьИзменения
Т.е. этот метод меняет номера сообщения, а можно ли их поменять как то по другому?
При этом в процессе выборки изменений в записи регистрации изменений проставляется номер сообщения обмена данными
Т.е. этот метод меняет номера сообщения, а можно ли их поменять как то по другому?
(5)Для чего вы их хотите менять? Они меняются автоматически, при загрузке корректного ответа от принимающей стороны после корректной загрузки входящего пакета.
Если удаленная сторона ничего не знает про номера сообщений, то самостоятельно присваивайте номер при регистрации изменений. В этом случае считайте, что удаленная сторона корректно загрузила все данные при каждой итерации обмена.
В этом случае вам хватит 3-х номеров сообщений: 1, 2 и 3 для какого-то очень специфичного случая, когда 2 первых пакета удаленной стороной не были приняты, в то время когда вам необходимо зарегистрировать изменения.
Если удаленная сторона ничего не знает про номера сообщений, то самостоятельно присваивайте номер при регистрации изменений. В этом случае считайте, что удаленная сторона корректно загрузила все данные при каждой итерации обмена.
В этом случае вам хватит 3-х номеров сообщений: 1, 2 и 3 для какого-то очень специфичного случая, когда 2 первых пакета удаленной стороной не были приняты, в то время когда вам необходимо зарегистрировать изменения.
(6) - сейчас попробую
(7)
На данный момент я вместе с данными выгружаю номер отправленного. В другой системе загружаю данные и передаю номер отправленного обратно. В 1С получаю номер и делаю так:ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
СтруктураВходящихДанных.НомерПринятого - он же изначально номер отправленного
Так вот в какой момент что должно измениться?
После того как я выгрузил все данные у них номер сообщения по прежнему NULL (Если не использовать ВыбратьИзменения )
После получения ответа удаляю регистрацию ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
Но после этого все изменения на месте, потому как этот метод удаляет регистрацию всех объектов с номером СтруктураВходящихДанных.НомерПринятого или меньше, а вот NULL он не меньше и не больше моего номера, поэтому он не удаляется. Соответственно при каждом обмене я буду передавать и новые изменения и старые, они будут накапливаться и рано или поздно я буду всю базу перекидывать принимающей стороне.
(7)
Они меняются автоматически, при загрузке корректного
- вот тут по подробнее, что значит корректный ответ, как его и что прописать в 1С.
На данный момент я вместе с данными выгружаю номер отправленного. В другой системе загружаю данные и передаю номер отправленного обратно. В 1С получаю номер и делаю так:ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
СтруктураВходящихДанных.НомерПринятого - он же изначально номер отправленного
Так вот в какой момент что должно измениться?
После того как я выгрузил все данные у них номер сообщения по прежнему NULL (Если не использовать ВыбратьИзменения )
После получения ответа удаляю регистрацию ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
Но после этого все изменения на месте, потому как этот метод удаляет регистрацию всех объектов с номером СтруктураВходящихДанных.НомерПринятого или меньше, а вот NULL он не меньше и не больше моего номера, поэтому он не удаляется. Соответственно при каждом обмене я буду передавать и новые изменения и старые, они будут накапливаться и рано или поздно я буду всю базу перекидывать принимающей стороне.
(8) В удаленной БД номер принятого должен быть = номеру отправленного локальной БД, если загрузка прошла корректно.
В локальной БД номер принятого сообщения = номеру отправленного удаленной БД в случае корректной загрузки ответа от удаленной БД.
Другими словами:
ЛокальнаяБД отправляет пакет #1 -> Удаленная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0, если ошибок не было, то 1.
Удаленная сторона отправляет пакет #1 - Локальная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0 и зарегистрированные изменения с номером 0 остануться. Если ошибок не было, то считается, что номер принятого сообщения - 1 и все изменения с номером 0 можно удалить, т.к. пакет корректно загружен удаленной БД.
В локальной БД номер принятого сообщения = номеру отправленного удаленной БД в случае корректной загрузки ответа от удаленной БД.
Другими словами:
ЛокальнаяБД отправляет пакет #1 -> Удаленная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0, если ошибок не было, то 1.
Удаленная сторона отправляет пакет #1 - Локальная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0 и зарегистрированные изменения с номером 0 остануться. Если ошибок не было, то считается, что номер принятого сообщения - 1 и все изменения с номером 0 можно удалить, т.к. пакет корректно загружен удаленной БД.
(10)
Так в том то и проблема, что нет у меня этим номеров 0(НОЛЬ), они для вновь зарегистрированных объектов равны NULL и этот самый NULL меняется на нужный номер только в момент вызова ВыбратьИзменения.
Т.е. записал документ, он попал в изменения с номером NULL, хотя в самом узле НомерОтпраленного = 100.
Запускаю выгрузку не используя (ВыбратьИзменения). Выгрузка проходит, блокировок ни каких нет, все гут. В другой системе принимаю сообщение, загружаю данные и отправляю ответ с номером 100.
Принимаю в 1С этот ответ и выполняю код ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
где СтруктураВходящихДанных.НомерПринятого - это 100, т.е. то что передали изначально.
Так вот удаление регистрации не происходит, потому что у меня по прежнему все изменения стоят с номером NULL
Удаленная сторона отправляет пакет #1 - Локальная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0 и зарегистрированные изменения с номером 0 остануться.
Так в том то и проблема, что нет у меня этим номеров 0(НОЛЬ), они для вновь зарегистрированных объектов равны NULL и этот самый NULL меняется на нужный номер только в момент вызова ВыбратьИзменения.
Т.е. записал документ, он попал в изменения с номером NULL, хотя в самом узле НомерОтпраленного = 100.
Запускаю выгрузку не используя (ВыбратьИзменения). Выгрузка проходит, блокировок ни каких нет, все гут. В другой системе принимаю сообщение, загружаю данные и отправляю ответ с номером 100.
Принимаю в 1С этот ответ и выполняю код ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
где СтруктураВходящихДанных.НомерПринятого - это 100, т.е. то что передали изначально.
Так вот удаление регистрации не происходит, потому что у меня по прежнему все изменения стоят с номером NULL
(6) я может не так понял, код должен быть таким?
Если такой, то ни чего не выходит, все равно идет блокировка до окончания выгрузки
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
Пока ВыборкаИзмененных.Следующий() Цикл
КонецЦикла;
ВыборкаИзмененных.Сбросить();
Если такой, то ни чего не выходит, все равно идет блокировка до окончания выгрузки
(9) Да, именно это я и предлагал. В типовом коде этот цикл содержит еще подсчет общего количества выбираемых данных. Но предлагая такое я исходил из того, что блокировка будет снята после завершения обхода. Очевидно ошибся.
На всякий случай спрошу. Извините, если вопрос покажется глупым. Вы случайно явно или неявно транзакцию не открываете перед выборкой данных?
На всякий случай спрошу. Извините, если вопрос покажется глупым. Вы случайно явно или неявно транзакцию не открываете перед выборкой данных?
(13) Внутри функции ВыполнитьОбмен транзакций не использую, хотя пробовал открывать транзакцию перед ПланыОбмена.ВыбратьИзменения и закрывать сразуу после, думал транзакция верхнего уровня при закрытии "утащит" и транзакцию нижнего - но ошибся.
Возможно транзакция накладывается перед функцией ВыполнитьОбмен - эта функция вызывается из операции моего вебсервиса, к которому обращается принмающая сторона. Про проверить это я не знаю как.
Возможно транзакция накладывается перед функцией ВыполнитьОбмен - эта функция вызывается из операции моего вебсервиса, к которому обращается принмающая сторона. Про проверить это я не знаю как.
(15) ОГРОМНОЕ СПАСИБО, получилось!!!!!!
В целом, проблема в том, что стояла галка "В транзакции" у свойства моего вебсервиса. Именно поэтому функция ВыбратьИзменения на момент выполнения блокировала все таблицы и не отпускала после выполнения.
Убрал вышеупомянутую галку, и все заработало. Блокировка теперь вызывается не на пол часа, а буквально на пару секунд.
В целом, проблема в том, что стояла галка "В транзакции" у свойства моего вебсервиса. Именно поэтому функция ВыбратьИзменения на момент выполнения блокировала все таблицы и не отпускала после выполнения.
Убрал вышеупомянутую галку, и все заработало. Блокировка теперь вызывается не на пол часа, а буквально на пару секунд.
Для того, что бы в изменения номера изменились с NULL например на 100, то нужно вызвать
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
НомерОтправленного в данном случае =100
Как раз в этот момент во всех изменениях с номером NULL номер меняется на 100, но и как раз в этот момент включается долбанутая транзакция, которая длится до окончания выгрузки данных, хотя дальше по коду я работаю только с запросами выгрузкой в файл.
Ниже код для отправки данных. ВходящиеДанные - структура с кодом узла и номером принятого сообщения
После этого я уже выбираю данные запросом, сериализую, пакую и отправляю, ни где по коду ниже не работаю ни с ВыборкаИзмененных ни с ПланыОбмена. Пробовал Обходить выборку в цикле, пробовал выборке присваивать Неопределено, пробовал сбрасывать выборку - все равно транзакция висит до самого последнего момента.
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
НомерОтправленного в данном случае =100
Как раз в этот момент во всех изменениях с номером NULL номер меняется на 100, но и как раз в этот момент включается долбанутая транзакция, которая длится до окончания выгрузки данных, хотя дальше по коду я работаю только с запросами выгрузкой в файл.
Ниже код для отправки данных. ВходящиеДанные - структура с кодом узла и номером принятого сообщения
Функция ВыполнитьОбмен(ВходящиеДанные)
СтруктураВходящихДанных=ВходящиеДанные.Получить();
ТСД=Неопределено;
СтруктураВходящихДанных.Свойство("Код",ТСД);
Если Не ЗначениеЗаполнено(ТСД) Тогда
Возврат Сериализовать(Неопределено);
КонецЕсли;
Узел = ПланыОбмена.ТСД.НайтиПоКоду(ТСД);
Если Не ЗначениеЗаполнено(Узел) Тогда
Возврат Сериализовать(Неопределено);
КонецЕсли;
ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
//ЗагрузитьДанные();
Если Не Узел.НомерПринятого=СтруктураВходящихДанных.НомерОтправленного Тогда
Об=Узел.ПолучитьОбъект();
Об.НомерПринятого=СтруктураВходящихДанных.НомерОтправленного;
Об.ДатаЗагрузки=ТекущаяДата();
Об.Записать();
КонецЕсли;
//После обработки входящих данных
НомерОтправленного=Узел.НомерОтправленного+1;
СтруктураВозврата=Новый Структура;
СтруктураВозврата.Вставить("Код",Узел.Код);
СтруктураВозврата.Вставить("НомерПринятого",Узел.НомерПринятого);
СтруктураВозврата.Вставить("НомерОтправленного",НомерОтправленного);
//Необходимо для установки номеров в плане обмена
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
ПоказатьПосле этого я уже выбираю данные запросом, сериализую, пакую и отправляю, ни где по коду ниже не работаю ни с ВыборкаИзмененных ни с ПланыОбмена. Пробовал Обходить выборку в цикле, пробовал выборке присваивать Неопределено, пробовал сбрасывать выборку - все равно транзакция висит до самого последнего момента.
Изменить номер сообщения регистрации:
ПланыОбмена.ЗарегистрироватьИзменения(Узел, ОбъектРегистрации); // Регистрируем заново, сбрасываем номер
Выборка = ПланыОбмена.ВыбратьИзменения(Узел, НовыйНомер, ОбъектРегистрации); // Устанавливаем новый номер
Пока Выборка.Следующий() Цикл
// Выбираем изменения для установки номера
КонецЦикла;
Вакансии
Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)