Имя: Пароль:
1C
1С v8
Фоновое задание в обработке проведения
0 Ryzeman
 
25.04.22
08:26
У документа есть подписка на событие обработка проведения. В рамках неё происходит пара "тяжёлых" запросов и создание подчинённых документов за записью ссылки в них. Я бы хотел поместить весь тяжёлый код в фон (делал через БСП - длительные операции), но в рамках новой, фоновой транзакции, изменения в базе данных не видны. С подобным уже сталкивался, решил сериализацией табличных частей и нужных мне реквизитов в структуру и передачу её параметром. Тут такое не пройдёт - придётся слишком много чего переписывать. Кто-нибудь сталкивался с такой проблемой и есть ли изящное решение без ухода в регламентное задание?
1 DGorgoN
 
25.04.22
08:29
"В рамках неё происходит пара "тяжёлых" запросов и создание подчинённых документов за записью ссылки в них" - поубивав бы..
2 Ryzeman
 
25.04.22
08:33
(1) Согласен, но писал не я. Моя задача это всё дело максимально ускорить минимальными усилиями :)
3 Мигрень
 
25.04.22
08:33
(1) легко решается запуском фонового задания
4 Ryzeman
 
25.04.22
08:48
(3) ну, не так уж и легко если есть проблемы как в (0). Или речь про регламентное? Мне оно не подходит.
5 PuhUfa
 
25.04.22
08:53
(0) >>создание подчинённых документов за записью ссылки в них
Запись ссылок куда?
6 Serg_1960
 
25.04.22
08:54
"изменения в базе данных не видны" - можно более подробно где именно они не видны? В открытых формах?
7 Simod
 
25.04.22
08:57
(0) Как собираешься отменять создание подчиненных документов при отказе проведения основного документа?
8 Кир Пластелинин
 
25.04.22
09:01
(7) + 1
9 Serg_1960
 
25.04.22
09:07
(7) Вызовом ещё одного фонового задания, "обратного" первому. "Я тебя породил, я тебя и убью"(с)
10 Ryzeman
 
25.04.22
09:35
(5) Там перекрёстно у нового документа в проводимы и назад.
11 Ryzeman
 
25.04.22
09:36
(7) Для этого это делается последней подпиской в самом конце с проверкой на отказ.
12 Ryzeman
 
25.04.22
09:38
(6) При чём тут формы? Записывается объект. Скажем, если это новый объект, то в подписке в обработке проведения ссылка на него уже будет существовать. И запросом можно выбрать его табличную часть, например. В фоновом же задании открывается новая транзакция, ссылка будет на новый пустой документ, а запрос по табличной части ничего не вернёт.
13 Кир Пластелинин
 
25.04.22
09:41
(11) а если потом кто то добавит еще одну подписку?)
14 Ryzeman
 
25.04.22
09:49
(13) Надавать ему по пальцам :) Если серьёзно, в этом плане у нас есть защиты от таких коллизий. Доработки по подпискам, которые влияют от отказов или могут к ним приводить все запихнуты в 1 процедуру на каждый документ, который стоит в конце. По (0) у кого-нибудь мысли есть? Не хочется ради такой мелочи перелопачивать всё :(
15 PuhUfa
 
25.04.22
09:58
(12) фоновое же ты запускаешь в самом конце подписки и транзакция проведения должна завершиться?
16 Ryzeman
 
25.04.22
09:59
(15) Сам механизм фонового задания именно что запускает отдельную независимую транзакцию, видимо, и на момент выполнения кода в ней результаты транзакции из подписки ещё не видны. В этом суть проблемы.
17 Ryzeman
 
25.04.22
10:03
Можно поэкспериментировать и паузу в 1 секунду добавить :-D Но это не решит ту же проблему с переданной ссылкой в параметре. Объект в фоновое задание не запихнуть параметром.
18 mistеr
 
25.04.22
10:05
(16) Не просто отельную транзакцию, а отдельный сеанс.
Нужно в фоновом дождаться, пока основная транзакция зафиксируется и изменения будут видны.
19 Serg_1960
 
25.04.22
10:07
(12) Sorry, понедельник, утро... Чисто теоретически, сам объект --> ПоместитьВоВременноеХранилище(), без движений документа.
Некрасивое решение: можно скопировать и записать в базу; после использования в фоновом задании - удалить.
20 Ryzeman
 
25.04.22
10:07
(18) Я это и имел ввиду, верно, там сеанс запускается. Возможно ли передать ссылку нового документа при этом?
21 Ryzeman
 
25.04.22
10:09
(19) чёт оба варианта какие то ужасные, но за наводки спасибо. Сам объект мало что даст и не лучше варианта с сериализацией.
24 PuhUfa
 
25.04.22
10:12
(17) Можно попробовать отвязаться от самого документа. И запускать фоновое задание из другого места. Например из РС или РН связанных с твоим документом.
25 Ryzeman
 
25.04.22
10:13
Кстати интересно, а что с ссылкой у объекта, который поместили во временное хранилище? Что вообще с ним происходит при помещении туда?
26 Ryzeman
 
25.04.22
10:14
(24) вот это интересная идея, спасибо, подумаю.
27 Serg_1960
 
25.04.22
10:25
(25) Чисто теоретически рассуждая, если учитывать что документ может быть записан без проведения, то самой ссылкой уже можно пользоваться в процедуре ПриЗаписи(), которая вызывается до ОбработкаПроведения().
28 Simod
 
25.04.22
10:29
(11) Нет такого понятия "последняя" подписка. Хоть практика показывает, что подписки на одно событие для объекта запускаются в порядке следования в дереве метаданных платформой не регламентирован порядок запуска. И завязываться на это нельзя.

(16) Проблема известная - платформа не имеет механизма запуска события "после окончания транзакции". Когда поднимется Infostart кину ссылку на статью. Может поможет.

В общем случае советую разнести события: после создания основного документа формировать очередь задания на создание подчиненнных (связанных) и отдельным заданием ее обрабатывать.
29 mistеr
 
25.04.22
10:30
(20) А в чем проблема передать ссылку?
30 Serg_1960
 
25.04.22
10:34
"А в чём проблема"(с) не использовать механизм отложенное проведение? :)
31 Ryzeman
 
25.04.22
10:35
(29) Для новых объектов её сеанс\транзакция фонового задания её не видит.
(28) Пока мне больше всего понравилась идея привязаться к РН и просто от него плясать. Тыркать регистратор не совсем красиво, конечно. Да и следующий кто будет разбираться где создаётся документ - прифигеет это искать. Гм, надо ещё подумать)
32 mistеr
 
25.04.22
10:37
(31) Еще раз повторю (18):

> Нужно в фоновом дождаться, пока основная транзакция зафиксируется и изменения будут видны.
33 Ryzeman
 
25.04.22
10:42
(32) ок интереса ради поиграюсь с паузой секунд в 5 как дойдут до этой задачи.Но даже если это поможет, решение выглядит ненадёжным.
34 mistеr
 
25.04.22
10:48
(33) Просто пауза конечно ненадежно. Нужно проверять запросом.
35 Ryzeman
 
25.04.22
11:04
(34) Да, ты абсолютно прав. Ожидание в несколько секунд решило проблему, и ссылку он определяет правильно. Видимо, он просто по ней не мог данные получить. Остаётся только дилемма как обезопасить схему и как не уйти в бесконечный цикл. Ну, это уже мои проблемы. Спасибо.
36 Serg_1960
 
25.04.22
11:05
Хех... а если тупо и без затей использовать ТранзакцияАктивна() для постановки фонового задания на "паузу"?
37 Ryzeman
 
25.04.22
11:12
(36) Для платформы это уже как другой сеанс. Т.е. ты как бы с двух сеансов выполняешь некие действия на сервере. Не думаю, что есть механизмы из первого увидеть транзакции второго.
38 Ryzeman
 
25.04.22
11:15
(37)+ А на все проверять как то страшновато.
39 Мигрень
 
25.04.22
11:21
я просто тупо сделал очередь на РС и фоновое задание автоматически проверяет эту очередь, после выполнения своей работы из очереди убирается ссылка на документ
40 Simod
 
25.04.22
11:29
41 Simod
 
25.04.22
11:31
(31) Лучше создать РС где записи это документы требующие обработки.
42 Ryzeman
 
25.04.22
12:31
(40) Спасибо.
Кому интересно, сделал в итоге так. Работает неплохо, но некоторая уязвимость всё равно есть.
В фоновую процедуру передаётся ДокументСсылка - ссылка на документ и ВерсияДанных - свойство ссылки. Затем внутри самой процедуры я их сверяю, если не совпадают - жду три секунды.

    ЧислоПопыток = 0;
    Пока ЧислоПопыток < 5 Цикл
        ЧислоПопыток = ЧислоПопыток + 1;    
        Если Версия = ДокументСсылка.ВерсияДанных Тогда  
            Прервать;
        Иначе
            Если ЧислоПопыток = 5 Тогда
                Возврат;
            КонецЕсли;  
            ОбщегоНазначенияБТС.Пауза(3);
        КонецЕсли;
    КонецЦикла;
43 timurhv
 
25.04.22
12:48
(42) А что, версия данных всегда меняется? :)
44 Fragster
 
гуру
25.04.22
12:51
в фоновом задании начинай транзакцию и пробуй установить блокировку на документ. как только транзакция записи/проведения документа завершиться - блокировка установится и все будет как надо.
45 Fragster
 
гуру
25.04.22
12:51
(42) фубля
46 Ryzeman
 
25.04.22
12:59
(43) Когда есть изменения в документе документе - да, всегда. Если изменений не было, то и ждать не надо.
(44) Какой тайм-аут у блокировки?
47 Fragster
 
гуру
25.04.22
13:02
(46) стандартный от базы, секунд двадцать. но если ты в себе уверен, то ты можешь это всё делать в цикле
48 Ryzeman
 
25.04.22
13:06
(47) Тогда не вижу принципиальной разницы кроме стилистической. Что там отвалится через 20 секунд в случае проблем что тут через 15. Блокировать саму запись мне не нужно - там в основном только чтение в запросе идёт. Самое грамотное решение было бы через РС и регламентное сделать, пожалуй, но пока мне это не подходит, если и буду переделывать в эту сторону, то потом и сразу всё. Сейчас просто попросили сделать что б посмотреть насколько это юзерам ускорит работу и стоит ли в этом направлении вообще двигаться.
49 Fragster
 
гуру
25.04.22
13:16
(48) принципиальная разница в скорости реакции (от окончания транзакции проведения документа до установки блокировки миллисекунды пройдут), независимости от ВК, работу не через "а мы уже приехали? а сейчас?".
50 Ryzeman
 
25.04.22
14:17
(49) Хорошая аналогия 😃 С одной стороны соглашусь, что так лучше и изящнее, с другой всё-таки опасаюсь нарваться на исключительную реакцию при блокировке. А если нагромождать попытками, то выйдет не лучше. Пока оставлю как есть, но за мнение спасибо)
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший