Проблема блокировок при работе с планом обмена |
Я |
06.04.21 — 12:46
Доброго времени суток!
Есть план обмен, работа с которым реализована следующим образом:
1) Получение данных из узла, присвоение выбранным данным «Номера сообщения» (для последующей очистки)
Функция ЗаполнитьСтруктуруИзмененийДляУзла_Справочники(УзелПланаОбмена, ИмяТаблицы)
РезультатФункции = Новый Структура(«ДанныеРегистрации, НомерИсходящегоСообщения»);
ОтобразитьСостояние(«Выборка изменений …»);
Если Метаданные.Справочники.Найти(ИмяТаблицы) <> Неопределено Тогда
Если ЗначениеЗаполнено(УзелПланаОбмена) Тогда
Запрос = Новый Запрос;
Запрос.Текст =»ВЫБРАТЬ ПЕРВЫЕ 3000
| Изменения.Ссылка КАК Объект
|ИЗ
| Справочник.» + ИмяТаблицы + «.Изменения КАК Изменения
|ГДЕ
| Изменения.Узел = &Узел»;
Запрос.УстановитьПараметр(«Узел», УзелПланаОбмена);
ДанныеРегистрации = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(«Объект»);
//
Если ДанныеРегистрации.Количество() > 0 Тогда
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
ЗаписьСообщения.НачатьЗапись(Запись, УзелПланаОбмена);
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, ДанныеРегистрации);
РезультатФункции.Вставить(«ДанныеРегистрации», ДанныеРегистрации);
РезультатФункции.Вставить(«НомерИсходящегоСообщения», ЗаписьСообщения.НомерСообщения);
ЗаписьСообщения.ЗакончитьЗапись();
Запись.Закрыть();
ВыборкаИзменений = Неопределено;
ЗаписьСообщения = Неопределено;
Запись = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат РезультатФункции;
КонецФункции
…
2) Происходит выгрузка сведений
…
3) Удаление из плана обмена успешно выгруженных данных (и не поменявшихся за момень выгрузки)
Функция ОчиститьИзмененияДляУзла_Справочники(УзелПланаОбмена, ИмяТаблицы, НомерСообщения, ДанныеУдаляемыеИзРегистрации)
РезультатФункции = Истина;
ОтобразитьСостояние(«Очистка изменений …»);
Если Метаданные.Справочники.Найти(ИмяТаблицы) <> Неопределено Тогда
Если ЗначениеЗаполнено(УзелПланаОбмена) И ЗначениеЗаполнено(НомерСообщения) И ЗначениеЗаполнено(ДанныеУдаляемыеИзРегистрации) Тогда
Запрос = Новый Запрос;
Запрос.Текст =»ВЫБРАТЬ
| Изменения.Ссылка КАК Объект,
| Изменения.НомерСообщения КАК НомерСообщения
|ИЗ
| Справочник.» + ИмяТаблицы + «.Изменения КАК Изменения
|ГДЕ
| Изменения.Узел = &Узел
| И Изменения.НомерСообщения > 0
| И Изменения.НомерСообщения <= &НомерСообщения
| И Изменения.Ссылка В(&ДанныеУдаляемыеИзРегистрации)
|»;
Запрос.УстановитьПараметр(«Узел», УзелПланаОбмена);
Запрос.УстановитьПараметр(«НомерСообщения», НомерСообщения);
Запрос.УстановитьПараметр(«ДанныеУдаляемыеИзРегистрации», ДанныеУдаляемыеИзРегистрации);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ПланыОбмена.УдалитьРегистрациюИзменений(УзелПланаОбмена, Выборка.Объект);
КонецЦикла;
Иначе
РезультатФункции = Ложь;
КонецЕсли;
Иначе
РезультатФункции = Ложь;
КонецЕсли;
Возврат РезультатФункции;
КонецФункции
1 — 06.04.21 — 12:48
После запуска этого механизма стала возникать ошибка блокировки:
Ошибка при вызове метода контекста (ВыбратьИзменения): Конфликт блокировок при выполнении транзакции:
Microsoft SQL Server Native Client 11.0: Транзакция (идентификатор процесса 55) вызвала взаимоблокировку ресурсов блокировка с другим процессом и стала жертвой взаимоблокировки. Запустите транзакцию повторно.
Т.е. блокировку вызывает вот эта строчка:
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, ДанныеРегистрации);
Нужна она мне для того, чтобы выбираемым данным назначить номер сообщения, по которому потом будет происходить зачистка.
2 — 06.04.21 — 12:52
Поиски в интернете показали, что Да «ПланыОбмена.ВыбратьИзменения» вызывает блокировку.
Но почему она длительная и мешает и как можно адекватно обойти ее — не понятно
3 — 06.04.21 — 12:57
Еще бы она не вызывала блокировку. Она же пишущая.
А вот почему другой процесс в нее упирается и какой именно процесс — вопрос.
Релиз, платформа, режим блокировок?
4 — 06.04.21 — 13:05
(3) «Релиз, платформа, режим блокировок» — платформа 8.3.15, режим блокировок «Автоматический»
«какой именно процесс в нее упирается» — могу предположить .что механизм, который регистрирует изменения в узел.
Понятно, что она пишущая. Не понятно, почему она на столько «блокирующая».
5 — 06.04.21 — 13:06
Как лучше обойти проблему с присвоением номера выбираемым данным я не нашел. Во всех источниках применяется примерно такая же логика.
6 — 06.04.21 — 13:25
(1) сделай обмен почаще, что бы порцайки не такие большие были
таблица плана обмена блокируется вся и наглухо… очень узкое место во всей концепции обменов на Планах
7 — 06.04.21 — 13:31
В режиме блокировок «Автоматический» для дедлока достаточно, чтобы оба процесса успели параллельно прочитать что-то нужное друг-другу для записи.
В управляемых блокировках это бы возникло только если бы они успели записать что-то нужное друг-другу для записи (так как де-факто управляемые блокировки сейчас на версионнике работают).
Но даже для первого варианта вроде эти звезды свести непросто. Хотя «Автоматический» еще эскалировать любит. Такое ощущение, что у тебя какие-то массированные пишущие регламенты крутятся, которые одно и то же могут перезаписывать. В итоге и таблица изменений постоянно большая и куча изменений тех же данных постоянно прилетает. Если это так, то попробуй развести их по времени хотя бы.
(6) Если бы она блокировалась вся и наглухо — то дедлоков бы не было. Был бы просто большой тайм-аут на блокировке и в худшем случае «опоздавшая» транзакция отваливалась бы по тайм-ауту.
8 — 06.04.21 — 13:32
Добавить в
Запрос.Текст =»ВЫБРАТЬ ПЕРВЫЕ 3000
| Изменения.Ссылка КАК Объект
|ИЗ
| Справочник.» + ИмяТаблицы + «.Изменения КАК Изменения
|ГДЕ
| Изменения.Узел = &Узел»;
ДЛЯ ИЗМЕНЕНИЯ
9 — 06.04.21 — 13:33
Это просто пучок Ванги в космос в надежде, что у тебя просто дедлок по повышению уровня изоляции.
10 — 06.04.21 — 13:39
(9) Тогда надо такое сделать одним запросом по всем выгружаемым справочникам. Тогда гарантия будет.
11 — 06.04.21 — 13:41
А зачем так вообще сделано? Зачем выгружать только справочники?
Почему вообще не свести это к единственному ВыбратьИзменения()?
12 — 06.04.21 — 13:44
Автор реплику справочников базы данных делает?
13 — 06.04.21 — 13:45
А ЗаполнитьСтруктуруИзмененийДляУзла_Справочники() случаем не в транзакции вызывается?
14 — 06.04.21 — 13:47
(11) А разница?
15 — 06.04.21 — 13:48
(13) Уже проверил — программно не увидел такого.
16 — 06.04.21 — 13:49
Есть ли какой-то принципиально другой вариант выбрать данные из плана обмена с присвоением номера сообщения?
Я вот что-то не вижу альтернатив. Прям альтернатива — убрать к чертям эти планы обмена и делать все на обычном РС.
17 — 06.04.21 — 13:52
(15) Странно. Тогда действительно разницы быть не должно. Тогда действительно может помочь совет (8)
18 — 06.04.21 — 13:57
(17) Попробую (8)
«Такое ощущение, что у тебя какие-то массированные пишущие регламенты крутятся, которые одно и то же могут перезаписывать. В итоге и таблица изменений постоянно большая и куча изменений тех же данных постоянно прилетает. Если это так, то попробуй развести их по времени хотя бы.»
Эти планы для регистрации элементов к выгрузке на сайт. Регламент выгрузки стартует каждые 3 минуты. Обычно очередь не очень большая, до 1000 элементов. Но иногда бывают «большие обмены», для этого ограничил размер порции 3000 элементами.
Механизм работает уже давно и довольно стабильно, но вот нашел одну «дырку», закрыть которую решил внедрением «ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, ДанныеРегистрации);» (ранее этой конструкции не было и из плана обмена удалялись все выгруженные элементы, без контроля НомераСообщения). «Дырку» закрыл, но появились ошибки блокировки.
19 — 06.04.21 — 14:02
Каждые три минуты у Вас вносятся изменения в тысячу и более записей справочников? Извини за вопрос не в тему: а что это у вас такое вообще?
20 — 06.04.21 — 14:06
(18) Только раз вышестоящей транзакции нет, то для (8) нужно запрос и регистрацию обрамить в транзакцию.
21 — 06.04.21 — 14:06
(19) К чему удивления? Ты не видел интернет-магазины у которых «новый заказ» падает каждые 2-3 секунды? В заказе от 1 до 10 единиц товара. Дальше идет обработка всего этого.
+ Розничные магазины — 30 штук.
+ Оптовый отдел.
22 — 06.04.21 — 14:06
Тьфу. Запрос и выборку изменений.
23 — 06.04.21 — 14:07
(21) Обычно при этом принято изменять документы, а не справочники.
24 — 06.04.21 — 14:07
емнип, но могу ошибаться — транзакция активна до окончания перебора выборки изменений
25 — 06.04.21 — 14:08
(19) «у Вас вносятся изменения в тысячу и более записей справочников» — не изменения вносятся в справочники, а возникают события, при которых элементы справочников нужно зарегистрировать к выгрузке во внешнюю системы.
26 — 06.04.21 — 14:09
(24) У меня вообще нет перебора выборки изменений
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
ЗаписьСообщения.НачатьЗапись(Запись, УзелПланаОбмена);
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, ДанныеРегистрации);
РезультатФункции.Вставить(«ДанныеРегистрации», ДанныеРегистрации);
РезультатФункции.Вставить(«НомерИсходящегоСообщения», ЗаписьСообщения.НомерСообщения);
ЗаписьСообщения.ЗакончитьЗапись();
Запись.Закрыть();
ВыборкаИзменений = Неопределено;
ЗаписьСообщения = Неопределено;
Запись = Неопределено;
27 — 06.04.21 — 14:09
Я понял, не нужно повторять.
28 — 06.04.21 — 14:11
(25) > возникают события, при которых элементы справочников нужно зарегистрировать к выгрузке во внешнюю системы
Зачем? Они поменялись? Почему? Или это банальная рекурсивная выгрузка всей используемой в заказах НСИ? Тогда зря.
29 — 06.04.21 — 14:12
(28) Сейчас не в этом вопрос. Давай не будем углубляться.
30 — 06.04.21 — 14:13
(26) значит пришло время регистрацию изменений переделать на регистр сведений
31 — 06.04.21 — 14:16
(30) Да, было бы здорово перевести на РС.
Если победить блокировки не удастся, то, видимо, придется именно так и сделать.
Вообще механизм планов обмена какой-то тупиковый. Метода написана 10 лет назад и никакой эволюции.
32 — 06.04.21 — 14:20
(29) Тогда просто попробуй (8), обрамив чтение и выборку в транзакцию. По-идее, это должно заставить процессы телебонькать таблицу изменений по очереди, а не на брудершафт.
(30) На РС у тебя тоже могут возникнуть похожие проблемы
(31) Метода была написана еще в 7.7
Эволюция автомата калашникова не может происходить бескомпромиссно. К более продвинутому инструменту у тебя будет еще больше вопросов.
33 — 06.04.21 — 14:29
(0) а зечем тебе механизм сообщений ?
Просто сам в коде удаляй регистрацию, если на сайт загрузилось и привет.
Тупо, план обмена регистрирует все изменения, ты их выгружаешь запросом на сайт и потом, по этой же выборке удаляешь регистрацию после обмена с сайтом. И Никаких номеров сообщений..
34 — 06.04.21 — 14:30
(33) а что будет, если в момент выгрузки изменений зарегистрируются новые? Без сообщений, данные изменения просто похерятся
35 — 06.04.21 — 14:30
Выбирай не по 3000, а по 1000
36 — 06.04.21 — 14:31
(34) И че ? Улетят при следующем обмене. Он отправит на сайт, только то, что запрос выгреб и по этой же выборке удалит изменения.
37 — 06.04.21 — 14:31
И ничего там не херится.
38 — 06.04.21 — 14:32
У автора есть простой выход: не пытаться втиснуть свой распухший обмен в регламент «каждые три минуты», а делать очередной обмен через три минуты после окончания предыдущего.
«Ну вот и славно! До свиданья… Да, а кислород попробуйте… и ванны.» — и запись всех изменений порциями в транзакции.
39 — 06.04.21 — 14:34
(33) У него так и было. Смотри (18). Но что-то он провтыкал, что таким образом решил полечить.
40 — 06.04.21 — 14:34
+ если по какой-то причине, на сайт загрузить не удалось, то просто не удаляешь регистрацию изменений.
Я у себя именно так и делал. И никаких номеров сообщений. Только узел обмена и привет.
41 — 06.04.21 — 14:36
(37) вот у тебя есть документ прихода, ты запустил выгрузку по плану обмена, формируешь файлик с остатками в разрезе номенклатуры и бац, в этот момент отменяют данный приход, но ты это изменение по документу не отработал и взял очистил полностью все изменения в плане обмена после успешной выгрузки. Далее ты изменения по этому документу не получишь, пока заново документ не перезапишешь. Поэтому и придумали номера сообщений, когда ты получаешь изменения, новые записи в план обмена уже попадают в разрезе нового номера сообщения.
42 — 06.04.21 — 14:38
(41) а далее весь букет неприятностей связанный с не верным остатком и отмененными заказами
43 — 06.04.21 — 14:40
(41) какой нах приход и тырнет магазин ?
44 — 06.04.21 — 14:42
*(38) хочу напомнить: автор формирует искусственно «порции» измененных данных, случайным образом попавших в выборку — имхо, на три минуты (а может быть и более) можно забыть про целостность и не противоречивость данных…
45 — 06.04.21 — 14:45
(33)(39)(40)
Возможна следующая ситуация:
В плане обмена зареганы товары «Т1», «Т2» и «Т3». Стартует обмен, выбирает все 3 элемента — посылает на выгрузку и ожидает ответа от внешней системы о успешном получении (все синхронно). Далее успешно выгруженные данные удаляются из плана обмена.
А в момент между «выбирает все 3 элемента — посылает на выгрузку» и «успешно выгруженные данные удаляются из плана обмена» возникает изменение элемента «Т2» (т.е. возникает потребность снова ег овыгрузить). И вот если НЕ использовать «номера сообщений», то в конце система просто затрет все 3 элемента. И Второй раз элемент «т2» уже не выгрузится.
46 — 06.04.21 — 14:46
(45) о чем я и писал в (41)
47 — 06.04.21 — 14:46
(46) ну да.
48 — 06.04.21 — 14:47
(45) да не вопрос, если этого боишься, то сразу грохай изменения. Потом выгружай на сайт, если не удачно — зарегь их. Все данные у тебя будут в выборке запроса.
49 — 06.04.21 — 14:47
И решить это можно либо «Номером сообщения» — если использовать планы обмена. Либо обычной «Дата регистрации в очереди», если использовать РС.
50 — 06.04.21 — 14:47
в свое время настраивал крупный хаб по обмену остатков поставщиков, где матрицы товаров исчислялись десятками тысяч. Несколько крупных оптовиков обменивались остатками между собой. Вот там номер сообщения для обмена был критически важен
51 — 06.04.21 — 14:49
(48) Плохая политика. Мне кажется так менее надежно.
52 — 06.04.21 — 14:49
(51) чем ? Что за пару мс у тебя что-то не зарегится ? У тебя там по 100’000 справочников летит всегда в обмене ?
53 — 06.04.21 — 14:50
(48) что значит удачно, неудачно? Выгрузка в основном всегда удачная, только в момент ее реализации могут быть еще изменения которые при очистке изменений в плане не попадут в следующую выгрузку, или я чего то не понимаю?
54 — 06.04.21 — 14:50
(44) Вот это вообще не понял. О какой целостности и противоречивости речь?
55 — 06.04.21 — 14:51
(53) это значит, что http запрос вернул не 200.
56 — 06.04.21 — 14:51
тырнет у тебя отвалился, еще чего
57 — 06.04.21 — 14:52
(53) Не удачная — это обработка ситуации, что на «принимающей» стороне произошел сбойошибка и данные не загрузились. Такое тоже бывает. Например, сайт «упал»
58 — 06.04.21 — 14:54
(52) Я полагаюсь на следующее — «гарантированно приняли данные — тогда удалили из очереди». А если удалять сразу, то больше вариантов потерять данные, если где-то что-то пойдет не так.
59 — 06.04.21 — 14:54
(57) в этом случае вообще никаких проблем нет, не очищаешь изменения и все. Я же говорю про случаи, когда в момент выгрузки происходят изменения, чем более нагруженная выгрузка по времени выполнения, тем больше шансов на такие моменты
60 — 06.04.21 — 14:57
(59) я прост не вижу проблемы в использовании номеров сообщений, получаешь изменения по последнему номеру, обрабатываешь их, если удачно отправил — очищаешь изменения с этим номером.
61 — 06.04.21 — 14:58
(54) Это просто для понимания: если есть изменения — то они должны быть переданы все и сразу, иначе у Вас может возникнуть ситуация, когда логически связанные между собой изменения будут «разорваны» — окажутся в различных сеансах обмена данными. Самый негативный момент — когда может возникнуть ситуация, что ранее зарегистрированное изменение не попадет ни в первую, ни во вторую «порцию» сеанса обмена — выборка таблицы изменений ведь по природе своей — случайна.
62 — 06.04.21 — 14:59
(61) это что то новенькое, первый раз такое слышу…можно на реальном примере?
63 — 06.04.21 — 15:07
(62) Это совсем не новость На реальном примере? Например, рИБ-обмен, особенность обмена: документы и их движения — автономны и независимы друг от друга. И всегда есть вероятность между обменами получить новые движения без изменения самого документа и/или измененный документ со «старыми» движениями. Само собой разумеется, что после очередного обмена всё само собой нормализуется.
64 — 06.04.21 — 15:13
(0) Блокировки управляемые у тебя?
Почитай вот эту статью, может разрешишь проблему с блокировками, тут в общих словах более менее разжевано, как работает план обмена со скулем
https://infostart.ru/1c/articles/561460/
65 — 06.04.21 — 15:16
(64) + еще вот тут есть схожая проблема и решение
https://forum.infostart.ru/forum9/topic230643/
66 — 06.04.21 — 15:34
Попытка автора читать и писать изменения «порциями» никоем образом не изменяет ситуацию с блокировками.
67 — 06.04.21 — 16:00
(66) насколько я понял, блокировка происходит при записи номера сообщения, когда получаешь выборку изменений. При управляемых блокировках, таблица не должна блокироваться, поэтому и ошибки с блокировками быть не должно
68 — 06.04.21 — 18:08
(67) Там нет единой таблицы как таковой. Имхо, в (64) об этом прямо сказано: ПланыОбмена.ВыбратьИзменения() поочередно обрабатывают каждую из таблиц изменений метаданных, а SQL Server, соответственно, для каждой из этих таблиц открывает/закрывает транзакцию — отсюда и эксклюзивные транзакционные блокировки таблицы.
69 — 06.04.21 — 18:12
(25) хрень какая то зачем сами элементы справочников повторно выгружать?
не логичнее документы?
Garykom
70 — 06.04.21 — 18:12
(69)+ или у вас остатки в номенклатуре?
-
Примерно неделю назад возникла ошибка при синхронизации:
«При загрузке сообщения обмена возникли ошибки: {Обработка.КонвертацияОбъектовИнформационныхБаз.МодульОбъекта(9152)}:Поле объекта не обнаружено (ФорматМагазина) ИначеЕсли НЕ ЭтоПараметрДляОбъекта.»База файловая.
УТ — Управление торговлей, редакция 11.1 (11.1.6.24)
РТ — Розница 8.3 Магазин автозапчастей, редакция 2.1 (2.1.2.8)До этого возникала ошибка:
«{ОбщийМодуль.ОбменДаннымиСервер.Модуль(1060)}: Ошибка при вызове метода контекста (ВыбратьИзменения)
Возврат ПланыОбмена.ВыбратьИзменения(Узел, НомерСообщения, ФильтрВыборки);
по причине:
Конфликт блокировок при выполнении транзакции:
Не удалось заблокировать таблицу ‘_ReferenceChngR3456’
по причине:
Не удалось заблокировать таблицу ‘_ReferenceChngR3456′»Которая исчезла(как я думаю) после работы в обработке «Регистрация изменений для обмена данными»
-
Скрин
Вложения:
-
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
-
Не знаю, скорее всего стандартные
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
Скорее всего ошибка в правилах
-
Попробовать другие правила? Как можно проверить правила это или нет?
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
Вам сообщение же выдало: Не найдено поле.
Вам нужны правила для вашей конфы, а не для типовой. -
Для УТ или РТ? Как тогда обмен работал до этого?
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
В смысле до этого ? До чего, этого?
-
До появления текущей ошибки.
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
Обновляли или изменяли конфигурации ?
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
Просто так ничего не бывает.
-
Возможно какая то таблица не правильно сохранилась «Конфликт блокировок при выполнении транзакции:
Не удалось заблокировать таблицу ‘_ReferenceChngR3456’ -
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
Тогда попробуйте ТИИ сделать, чудес не бывает
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
Можно все установить. НО перед этим обязательно сделайте копию базы
-
ТИИ сделал, ошибка сохраняется.
Вложения:
-
Offline
alexburn
Модераторы
Команда форума
Модератор- Регистрация:
- 5 янв 2009
- Сообщения:
- 15.150
- Симпатии:
- 560
- Баллы:
- 204
Попробуйте может кеш очистить, но не думаю что поможет. Сдается мне что вы обновили конфу
-
Если только конфа обновилась сама))
IKSparrow |
|
||
---|---|---|---|
|
Необходимо перетащить документ из одной конфигурации в другую. Используя планы обменов. Нарисовал схему переноса документа в КД. В правилах выгрузки данных в обработчике «Перед выгрузкой данных» написал следующий код (руководствовался этой ссылкой: ССЫЛКА
:Код 1C v 8.х
Так вот самое интересное, что если обработку «УниверсальныйОбменДаннымиВФорматеXML» (V8Exchan81.epf) с этими правилами, то всё отлично выгружается/загружается. А вот если задействовать штатный механизм «Настройки обмена данными», указать там эти правила и попытаться совершить обмен, то будет ругаться на вторую строчку: Ошибка в обработчике события ПередВыгрузкойДанных (конвертация) вышеприведённого кода. То ли я не понимаю механизма и не то и не там использую то ли… В общем, как исправить проблему? |
Yandex |
|
||
---|---|---|---|
|
IKSparrow |
|
||
---|---|---|---|
|
Вот всё настраивал согласно этому документу. Ошибка такая же. |
E_Migachev |
|
||
---|---|---|---|
|
(0) IKSparrow, хм… что тут не подскажу *11, |
Подсказка: Для выделения Кода используйте (в редакторе). |
Согласно документации 1С в методе ВыбратьИзменения глобального контекста ПланыОбмена есть параметр «ФильтрВыборки». Общий синтаксис: ВыбратьИзменения(<Узел>, <НомерСообщения>, <ФильтрВыборки>). При использовании третьего параметра возникло затруднение. Фильтр накладывается на ряд записей регистра сведений, подчиненного регистратору. Запросом выбираются регистраторы, создаются наборы записей регистра с отбором по регистраторам и помещаются в массив. Этот массив далее используется как третий параметр. Но при этом в выборку, которая возвращается методом ВыбратьИзменения, попадают требуемые отобранные записи регистра (остальные не попадают) и ВСЕ изменения всех остальных регистров. Кто-нибудь использовал фильтр выборки? Это штатное поведение системы?
в этот массив добавь ещё Метаданные регистра
Если не ошибаюсь, то в ФильтрВыборки надо ложить не ссылки на объекты данных, а названия метаданных…
Ошибка при вызове метода контекста (ВыбратьИзменения): Фильтр изменений содержит значение неверного типа — Регистр сведений набор записей
какая религия мешает прочитать справку целиком? Все же написано <ФильтрВыборки> (необязательный) Тип: Неопределено; Объекты метаданных; СсылкаНаОбъект, НаборЗаписей, Массив. Неопределено — фильтр пуст, выбираются все изменения по узлу; Объекты метаданных — выбираются изменения в основной таблице, связанной с данным объектом метаданных; СсылкаНаОбъект — фактически, может быть выбрана только одна запись об изменении данного объекта, либо ни одной, если объект не менялся; НаборЗаписей — набор записей регистра, может быть не выбран, для фильтрации изменений используется лишь отбор набора записей; Массив — все элементы массива имеют один из перечисленных выше типов, кроме Неопределено. Условия фильтрации соединяются по ИЛИ.
согласно СП можно использовать и ссылки на конкретные объекты, и наборы записей регистров и метаданные
там же написано, что когда используешь наборы записей, от них реально используются только ОТБОРЫ
и? у автора отбор по регисратору, всё правильно. Вопрос был — с какого бодуна там записи других регистров
я так и написал. На набор записей накладывается отбор и все. Набор при этом даже не читается. И по этому конкретному регистру все ОК. Но попадают и ВСЕ записи ВСЕХ остальных регистров.
Меня смущает в СП фраза «Условия фильтрации соединяются по ИЛИ»…
меня не смущает, всё правильно. Если б было И — ничего бы не выбиралось вобще, когда в массиве больше одной записи
полагаю дело в том, что в фильтре выборки есть еще что-то, кроме набора записей
там есть только переданный массив. Он правильно показывается в отладчике
может в платформе косяк? на другой проверить бы, на 8.2 какойнить
а в массиве-то только набор записей или что-то еще? А платформа у тебя какая?
в массиве несколько элементов типа «РегистрСведенийНаборЗаписей». И все
попробуй один элемент передать, изменения остальных регистров будут в выборке? Или может там в других наборах отбора где-то нет?
пробовал. То же самое. Одна запись нужного регистра и все остальные регистры целиком
Всем спасибо. В массив фильтра выборки нужно добавлять пустые наборы записей без отборов остальных регистров, участвующих в плане обмена. Тогда работает. Фраза «Условия фильтрации соединяются по ИЛИ» стала понятной
Тэги: 1С 8
Комментарии доступны только авторизированным пользователям
vicof
3 — 29.10.13 — 12:40
ПланыОбменаМенеджер (ExchangePlansManager)
УдалитьРегистрациюИзменений (DeleteChangeRecords)
Синтаксис:
УдалитьРегистрациюИзменений(<Узлы>, <Данные>)
Параметры:
<Узлы> (обязательный)
Тип: ПланОбменаСсылка.<Имя плана обмена>; Массив.
Одиночное значение типа ПланОбменаСсылка.<Имя плана обмена> или массив таких значений, показывающие для каких узлов удаляются записи регистрации изменений.
<Данные> (необязательный)
Тип: Метаданные, Неопределено; УдалениеОбъекта; Число; <Данные>.
Значением данного параметра может быть объект метаданных, объект, представляющий данные, хранимые в базе данных, такой как документ, элемент справочника, счет бухгалтерского учета, менеджер записи константы, набор записей регистра и т. п., ссылка на объект базы данных, а также Неопределено.
Если указан объект метаданных, то записи регистрации изменений будут удалены для всех элементов данных, относящихся к указанному объекту метаданных. Объект метаданных должен входить в состав планов обмена всех узлов, указанных в первом параметре.
Если указан УдалениеОбъекта, то удаление записи регистрации изменений выполняется для объекта базы данных, на который «указывает» ссылка, содержащаяся в объекте УдалениеОбъекта.
Если указан объект представляющий данные, хранимые в базе данных, или ссылка, то записи регистрации изменений будут удалены только для указанных данных. Объект метаданных, соответствующий данным должен входить в состав всех планов обмена всех узлов, указанных в первом параметре.
Если указано Неопределено или не указан, то в качестве первого параметра может быть указан только одиночный узел. И в этом случае записи регистрации изменений будут удалены для всех объектов, метаданные которых входят в состав плана обмена, к которому относится узел, указанный в качестве первого параметра.
Если в качестве первого параметра указан одиночный узел, то в параметре может быть указан номер сообщения. В этом случае метод УдалитьРегистрациюИзменений удаляет из всех таблиц регистрации изменений все записи относящиеся к указанному узлу, у которых номер сообщения меньше или равен значению второго параметра.
Значение по умолчанию: Неопределено
Описание:
Удаляет записи регистрации изменений одного или группы элементов данных для одного или нескольких узлов планов обмена.
Доступность:
Сервер, толстый клиент, внешнее соединение.
Пример:
// Пример 1
Спр = Справочники.Валюты.НайтиПоКоду(«810»);
Узел = ПланыОбмена.ПО1.НайтиПоКоду(«Офис»);
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Спр);
// Пример 2
// Загрузка из файла
// Производим попытку открытия файла
ЧтениеXML = Новый ЧтениеXML;
Попытка
ЧтениеXML.ОткрытьФайл(ИмяФайла);
Исключение
Возврат;
КонецПопытки;
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
Если ЧтениеСообщения.Отправитель <> Ссылка Тогда
// Сообщение предназначено не для этого узла
ВызватьИсключение «Неверный узел»;
КонецЕсли;
// Удаляем регистрацию изменений для узла отправителя сообщения
ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
Sasha_H
7 — 29.10.13 — 12:47
(6) дополнение
Удаляют с регистрации обычно то что есть там используя обход результатом запроса или через ВыбратьИзменения, а не просто в лоб УдалитьРегистрацию.
Там есть нюансы с новыми элементами и что ты написал в (0) то что второй элемент это Тип ну дык он и не записан будет содержать Тип Ссылку.
Взял пример из книги «Профессиональная разработка в системе 1С 8», стр 584. «Удаление регистрации изменений по узлу»: При выполнении кода выскакивает ошибка: {ВнешняяОбработка.ВнешняяОбработка2}: Ошибка при вызове метода контекста (УдалитьРегистрациюИзменений): Недопустимое значение параметра (параметр номер ‘2’) ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена); по причине: Недопустимое значение параметра (параметр номер ‘2’) Второй параметр не передаю. Что не так, не пойму.
Чему равен «Узел»? СП: Если указано Неопределено или не указан, то в качестве первого параметра может быть указан только одиночный узел.
Такой код сработал, но надо удалить все изменения.
В цикле по всем узлам и для каждого ПланыОбмена.УдалитьРегистрациюИзменений(Узел);
{ВнешняяОбработка.ВнешняяОбработка2}: Ошибка при вызове метода контекста (УдалитьРегистрациюИзменений): Недопустимое значение параметра (параметр номер ‘2’) ПланыОбмена.УдалитьРегистрациюИзменений(Выборка.Ссылка); по причине: Недопустимое значение параметра (параметр номер ‘2’) Вот код:
Должен работать! И без ошибок! Вот более полный код :))
{ВнешняяОбработка.ВнешняяОбработка2}: Ошибка при вызове метода контекста (УдалитьРегистрациюИзменений): Недопустимое значение параметра (параметр номер ‘2’) ПланыОбмена.УдалитьРегистрациюИзменений(Выборка.Ссылка); по причине: Недопустимое значение параметра (параметр номер ‘2’) У кого еще есть варианты )
Тупит платформа Специально для тупых — дай ей второй параметр :)) …(Выборка.Ссылка, Неопределено);
{ВнешняяОбработка.ВнешняяОбработка2}: Ошибка при вызове метода контекста (УдалитьРегистрациюИзменений): Недопустимое значение параметра (параметр номер ‘2’)
Вот уж действительно гы-гы-гы. Ставьте точку останова — хватит над здравым смыслом шутить… и смотрите в мониторе что из себя представляет Выборка.Ссылка — может быть у Вас в базе узлы «пустые» внесены?
Специально сделал копию и запустил алгоритм. Отработало без ошибок. Проверил обменом — пусто. Действительно, — регистрацию снесло всю напрочь.
Отладчик: Выборка.Ссылка тип ПланОбменаСсылка.Главный Код «2 » Строка Наименование «Перефирия» Строка НомерОтправленного 30 Число НомерПринятого 0 Число ПометкаУдаления Ложь Булево Вроде все в норме.
Эээ… У меня РИБ-база… уж третий год работает на разных релизах…
У меня не РИБ, просто настроил планы обмена. Интересно может в этом проблема.
Не-а, — это роли не играет. Планы обмена что РИБ, что не РИБ — свойства и методы одинаковые, — кроме СоздатьНачальныйОбраз… Всё, — продуктивных мыслей нет… Может выйти из программы и конфигуратора и зайти вновь?
Даже комп перезагрузил. Видимо буду стирать как в
Сейчас на партнерский выложу, интерестно что скажут.
Тэги:
Комментарии доступны только авторизированным пользователям
В платформе 1С сообщения об ошибках бывают достаточно запутаны, и без должных навыков разобраться в причинах достаточно сложно. Вот и сообщение об ошибке при вызове контекста может ввести в ступор начинающего разработчика. Однако в подавляющем большинстве случаев мы видим подобное сообщение, если разработчик допустил ошибку в своем коде. Причем речь зачастую идет не об орфографических ошибках, а о логических.
Исправляем ситуацию
Чтобы избавиться от этого неприятного сообщения об ошибке при вызове метода контекста, следует понимать, что контекстом называют методы платформы 1С. Значит в определенной строке кода воспользовались методом с неверными параметрами или вызвали его не от того владельца. Всегда внимательно и полностью читайте сообщения об ошибках – часто в них содержится указание на строку и метод, вызвавший ошибку. Это поможет сэкономить время на отладку и поиск проблемного места в коде.
Рассмотрим действия разработчика на примере со специально допущенной ошибкой. Мы запускаем на исполнение нижеприведенный кусок кода с запросом, в котором забыли дописать условие отбора. Компилятор 1С пропускает такую процедуру, так как орфографических ошибок в написании команд мы не допустили. Однако в режиме предприятия нас ждет такое сообщение об ошибке:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.ВерсияДанных КАК ВерсияДанных,
| Номенклатура.ПометкаУдаления КАК ПометкаУдаления,
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.ЭтоГруппа КАК ЭтоГруппа,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул,
| Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| Номенклатура.ТипНоменклатуры КАК ТипНоменклатуры,
| Номенклатура.Предопределенный КАК Предопределенный,
| Номенклатура.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| ";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
КонецЦикла;
Приведенный текст ошибки программисту 1С скажет, что в модуле формы обработки «ЧтениеЗаписьXML на 152 строчке кода не может выполниться запрос. Причина в том, что на 17 строчке запроса нет чего-то, что ждал компилятор. Таким образом, чтобы убрать подобное сообщение, необходимо выяснить, что там должно быть и написать недостающий код.
Увидев вышеприведенный кусок кода, разработчик заметит, что в запросе есть служебное слово «ГДЕ», дающее сигнал 1С, что дальше будет условие. Но мы забыли дописать его и, естественно, система с помощью сообщения об ошибке спрашивает нас – «а где условие?». Чтобы исправить эту ситуацию необходимо либо убрать оператор «ГДЕ» из запроса, либо добавить условие.
Но ошибки могут быть не только в текстах запросов. Допустим, мы хотим выбрать всю номенклатуру и узнать, входит ли она в определенную группу. Проверка происходит с помощью метода «ПринадлежитЭлементу» и его параметра, который должен быть типа СправочникСсылка. Мы опять допускаем ошибку и вместо ссылки в параметр метода помещаем строку, содержащую имя переменной.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.ВерсияДанных КАК ВерсияДанных,
| Номенклатура.ПометкаУдаления КАК ПометкаУдаления,
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.ЭтоГруппа КАК ЭтоГруппа,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул,
| Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| Номенклатура.ТипНоменклатуры КАК ТипНоменклатуры,
| Номенклатура.Предопределенный КАК Предопределенный,
| Номенклатура.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа ";
НужнаяГруппаЭлементов = Справочники.Номенклатура.НайтиПоНаименованию("Мебель");
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Сообщить(ВыборкаДетальныеЗаписи.Ссылка.ПринадлежитЭлементу("НужнаяГруппаЭлементов"));
КонецЦикла;
1С выдает настолько же информативное сообщение, из которого мы понимаем, что на 158 строке у 1 параметра неправильный тип. Но что же делать, если мы не знаем, какой тип должен быть? В этом нам поможет Синтакс-помощник, встроенный в платформу 1С.
В конфигураторе находим строку и метод, на который указывало сообщение об ошибке, и нажимаем на него правой кнопкой мыши. Выбираем пункт «Поиск в синтакс-помощнике» и платформа самостоятельно ищет справочную информацию по выделенному методу. В справке мы видим не только подробное описание параметров и самого метода, но и пример. Сверив пример с нашим кодом, приходит понимание, что кавычки не нужны и без них все работает.
Чаще всего причиной подобных ошибок выступают следующие факторы:
- Невнимательность;
- Отсутствие опыта или знаний;
- Несогласованность действий разработчиков друг с другом;
- Изменения в методах контекста в новых версиях платформы.
Но ошибки при разработке ПО случаются постоянно, поскольку иногда ошибаются даже специалисты с многолетним опытом. Самое главное – уметь исправлять их и учиться на них. Постепенно вы будете видеть сообщения об ошибках все реже и научитесь замечать подобные «опечатки» еще до запуска 1С.