ПланыОбмена.ВыбратьИзменения() - в какой момент закрывается транзакция? Как избавиться от конфликтов блокировок?

1. НовенькийЯ 27.11.19 11:06 Сейчас в теме
Добрый день.
Столкнулся с проблемой транзакция при выгрузке больших объемов данных использую механизм планов обмена.
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);

после этой строки блокируется запись всех объектов, входящих в состав текущего плана обмена.
Сама строка выполняется быстро, через консольку смотрю, номера обмена проставлены, но все еще висит транзакция.
В какой момент она закрывается? как ее закрыть принудительно.
Не знаю важно это или нет, вся работа идет в модуле вебсервиса, и транзакция завершается только после того, как отработает полностью весь код обмена.
Получается так:
1 - проставляю номера обмена в зарегистрированных данных в текущем узле - эта операция проходит быстро.
2 - получение измененных с помощью запроса - тоже быстрая операция
3 - выгружаю данные в файл - эта операция длительная и пока она не отработает, в 1С работать не возможно - конфликт блокировок.

Может есть способ проставить НомерСообщения в изменениях не использую ВыбратьИзменения
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. nomad_irk 71 27.11.19 11:13 Сейчас в теме
(1) Транзакция закроется после обхода всей выборки.
избавится от конфликта бликировок можно путем отказа от ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного) совсем, вместо этого делать запрос вида:
Выбрать Ссылка Из Справочник.<ИмяСправочника>.Изменения ГДЕ Узел = &Узел и НомерСообщения = &НомерСообщения
3. НовенькийЯ 27.11.19 11:21 Сейчас в теме
(2) это хорошо, я так и делаю, только проблема в том, что в момент выборки документов и отправки данных, происходит запись объектов, они регистрируются в ПО с номером =0(точнее null)
И если не вызывать ПланыОбмена.ВыбратьИзменения, то этот самый номер сообщения не изменится для объектов, которые я уже выгрузил. Затем от принимающей стороны приходит ответ с номером принятого сообщения и должен удалить регистрацию объхектов с необходимым номером. И как мне это сделать?
4. nomad_irk 71 27.11.19 11:25 Сейчас в теме
(3) Удалить регистрацию по номеру можно с помощью:
ПланыОбмена.УдалитьРегитстрациюИзменений(Узел, НомерСообщения)
5. НовенькийЯ 27.11.19 11:28 Сейчас в теме
Вот кусок из справки по ВыбратьИзменения
При этом в процессе выборки изменений в записи регистрации изменений проставляется номер сообщения обмена данными

Т.е. этот метод меняет номера сообщения, а можно ли их поменять как то по другому?
7. nomad_irk 71 27.11.19 11:34 Сейчас в теме
(5)Для чего вы их хотите менять? Они меняются автоматически, при загрузке корректного ответа от принимающей стороны после корректной загрузки входящего пакета.

Если удаленная сторона ничего не знает про номера сообщений, то самостоятельно присваивайте номер при регистрации изменений. В этом случае считайте, что удаленная сторона корректно загрузила все данные при каждой итерации обмена.
В этом случае вам хватит 3-х номеров сообщений: 1, 2 и 3 для какого-то очень специфичного случая, когда 2 первых пакета удаленной стороной не были приняты, в то время когда вам необходимо зарегистрировать изменения.
6. dhurricane 27.11.19 11:33 Сейчас в теме
(2) (3) Можно попробовать провернуть "финт ушами", который кстати используется и в типовых конфигурациях (правда я и не догадывался, что это финт). Обойти всю выборку без выгрузки, затем сбросить ее и уже обходить заново, попутно выгружая данные.
8. НовенькийЯ 27.11.19 11:43 Сейчас в теме
(6) - сейчас попробую
(7)
Они меняются автоматически, при загрузке корректного
- вот тут по подробнее, что значит корректный ответ, как его и что прописать в 1С.

На данный момент я вместе с данными выгружаю номер отправленного. В другой системе загружаю данные и передаю номер отправленного обратно. В 1С получаю номер и делаю так:ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
СтруктураВходящихДанных.НомерПринятого - он же изначально номер отправленного

Так вот в какой момент что должно измениться?

После того как я выгрузил все данные у них номер сообщения по прежнему NULL (Если не использовать ВыбратьИзменения )
После получения ответа удаляю регистрацию ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
Но после этого все изменения на месте, потому как этот метод удаляет регистрацию всех объектов с номером СтруктураВходящихДанных.НомерПринятого или меньше, а вот NULL он не меньше и не больше моего номера, поэтому он не удаляется. Соответственно при каждом обмене я буду передавать и новые изменения и старые, они будут накапливаться и рано или поздно я буду всю базу перекидывать принимающей стороне.
10. nomad_irk 71 27.11.19 11:57 Сейчас в теме
(8) В удаленной БД номер принятого должен быть = номеру отправленного локальной БД, если загрузка прошла корректно.
В локальной БД номер принятого сообщения = номеру отправленного удаленной БД в случае корректной загрузки ответа от удаленной БД.

Другими словами:

ЛокальнаяБД отправляет пакет #1 -> Удаленная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0, если ошибок не было, то 1.
Удаленная сторона отправляет пакет #1 - Локальная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0 и зарегистрированные изменения с номером 0 остануться. Если ошибок не было, то считается, что номер принятого сообщения - 1 и все изменения с номером 0 можно удалить, т.к. пакет корректно загружен удаленной БД.
11. НовенькийЯ 27.11.19 12:06 Сейчас в теме
(10)
Удаленная сторона отправляет пакет #1 - Локальная БД загружает, если в процессе загрузки произошли ошибки, то номер принятого сообщения останется 0 и зарегистрированные изменения с номером 0 остануться.

Так в том то и проблема, что нет у меня этим номеров 0(НОЛЬ), они для вновь зарегистрированных объектов равны NULL и этот самый NULL меняется на нужный номер только в момент вызова ВыбратьИзменения.

Т.е. записал документ, он попал в изменения с номером NULL, хотя в самом узле НомерОтпраленного = 100.
Запускаю выгрузку не используя (ВыбратьИзменения). Выгрузка проходит, блокировок ни каких нет, все гут. В другой системе принимаю сообщение, загружаю данные и отправляю ответ с номером 100.
Принимаю в 1С этот ответ и выполняю код ПланыОбмена.УдалитьРегистрациюИзменений(Узел,СтруктураВходящихДанных.НомерПринятого);
где СтруктураВходящихДанных.НомерПринятого - это 100, т.е. то что передали изначально.
Так вот удаление регистрации не происходит, потому что у меня по прежнему все изменения стоят с номером NULL
9. НовенькийЯ 27.11.19 11:55 Сейчас в теме
(6) я может не так понял, код должен быть таким?
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
	Пока ВыборкаИзмененных.Следующий() Цикл

	КонецЦикла;
	ВыборкаИзмененных.Сбросить();

Если такой, то ни чего не выходит, все равно идет блокировка до окончания выгрузки
13. dhurricane 27.11.19 12:26 Сейчас в теме
(9) Да, именно это я и предлагал. В типовом коде этот цикл содержит еще подсчет общего количества выбираемых данных. Но предлагая такое я исходил из того, что блокировка будет снята после завершения обхода. Очевидно ошибся.

На всякий случай спрошу. Извините, если вопрос покажется глупым. Вы случайно явно или неявно транзакцию не открываете перед выборкой данных?
14. НовенькийЯ 27.11.19 12:42 Сейчас в теме
(13) Внутри функции ВыполнитьОбмен транзакций не использую, хотя пробовал открывать транзакцию перед ПланыОбмена.ВыбратьИзменения и закрывать сразуу после, думал транзакция верхнего уровня при закрытии "утащит" и транзакцию нижнего - но ошибся.
Возможно транзакция накладывается перед функцией ВыполнитьОбмен - эта функция вызывается из операции моего вебсервиса, к которому обращается принмающая сторона. Про проверить это я не знаю как.
15. dhurricane 27.11.19 12:44 Сейчас в теме
(14) Методом ТранзакцияАктивна().
16. НовенькийЯ 27.11.19 12:56 Сейчас в теме
(15) да, транзакция активна с самого начала выполнения функции. и есть кой какие догадки, сейчас проверю, но кажется все должно сработать. 5 минут и дам ответ.
17. НовенькийЯ 27.11.19 13:02 Сейчас в теме
(15) ОГРОМНОЕ СПАСИБО, получилось!!!!!!

В целом, проблема в том, что стояла галка "В транзакции" у свойства моего вебсервиса. Именно поэтому функция ВыбратьИзменения на момент выполнения блокировала все таблицы и не отпускала после выполнения.

Убрал вышеупомянутую галку, и все заработало. Блокировка теперь вызывается не на пол часа, а буквально на пару секунд.
21. user602809_oleg4mok 02.04.20 10:33 Сейчас в теме
(17) У меня похожая ситуация. Делаю обмен на HTTP сервисах и тоже споткнулся на ПланыОбмена.ВыбратьИзменения. Что значит фраза "стояла галка "В транзакции" у свойства моего вебсервиса" ?
22. НовенькийЯ 02.04.20 12:21 Сейчас в теме
(21) Общие- Web-сервисы - ТвойСервис - посомтри свойства твоих операций, среди свойств будет галка В ТРАНЗАКЦИИ - убери
19. tormozit 7136 27.11.19 15:32 Сейчас в теме
(2)
Транзакция закроется после обхода всей выборки.

Это - неверное утверждение. Транзакция открывается и закрывается внутри этого метода.
23. Maximum.proger 08.12.20 22:16 Сейчас в теме
(2) блокировка только в транзакции выполнения ВыбратьИзменения накладывается. Обход выборки без блокировок. У человека ранее начата транзакция скорее всего.
12. НовенькийЯ 27.11.19 12:19 Сейчас в теме
Для того, что бы в изменения номера изменились с NULL например на 100, то нужно вызвать
ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
НомерОтправленного в данном случае =100
Как раз в этот момент во всех изменениях с номером NULL номер меняется на 100, но и как раз в этот момент включается долбанутая транзакция, которая длится до окончания выгрузки данных, хотя дальше по коду я работаю только с запросами выгрузкой в файл.

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

	
	//После обработки входящих данных
	
	НомерОтправленного=Узел.НомерОтправленного+1;
	
	СтруктураВозврата=Новый Структура;
	СтруктураВозврата.Вставить("Код",Узел.Код);
	СтруктураВозврата.Вставить("НомерПринятого",Узел.НомерПринятого);
	СтруктураВозврата.Вставить("НомерОтправленного",НомерОтправленного);
		
	//Необходимо для установки номеров в плане обмена
	ВыборкаИзмененных=ПланыОбмена.ВыбратьИзменения(Узел,НомерОтправленного);
Показать

После этого я уже выбираю данные запросом, сериализую, пакую и отправляю, ни где по коду ниже не работаю ни с ВыборкаИзмененных ни с ПланыОбмена. Пробовал Обходить выборку в цикле, пробовал выборке присваивать Неопределено, пробовал сбрасывать выборку - все равно транзакция висит до самого последнего момента.
18. nomad_irk 71 27.11.19 13:37 Сейчас в теме
(12) В таком случае, запросом получайте зарегистрированные изменения, а номер сообщения присваивайте самостоятельно Узел.НомерОтправленного = НомерОтправленного
20. PlatonStepan 38 28.11.19 06:14 Сейчас в теме
А вы пользуетесь объектом ЗаписьСообщенияОбмена?
Этот объект организует доступность, начало и окончание процесса выгрузки.
24. Nicholas 887 24.03.22 08:37 Сейчас в теме
Изменить номер сообщения регистрации:
ПланыОбмена.ЗарегистрироватьИзменения(Узел, ОбъектРегистрации); // Регистрируем заново, сбрасываем номер
Выборка = ПланыОбмена.ВыбратьИзменения(Узел, НовыйНомер, ОбъектРегистрации); // Устанавливаем новый номер
Пока Выборка.Следующий() Цикл
    // Выбираем изменения для установки номера
КонецЦикла;
maksa2005; +1 Ответить
Оставьте свое сообщение
Вакансии
1С аналитик
Москва
зарплата от 210 000 руб.
Полный день

Руководитель направления 1С
Москва
зарплата от 350 000 руб.
Полный день

1С Программист
Москва
зарплата от 180 000 руб.
Полный день

Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)