Имя: Пароль:
1C
1С v8
Как в фоновом задании узнать завершено ли проведение документа
0 DrWeb
 
28.05.20
15:24
Добрый день, коллеги! Сразу оговорюсь. Это читал: v8: Как узнать транзакция в текущий момент есть ?

Тем не менее есть реальный кейс, требующий узнать завершилась ли транзакция. Необходимо сделать онлайн обновление остатков во внешней системе.
Изначально идея была такой: Сделать подписку на событие РегистрНакопленияНаборЗаписей.ТоварыНаСкладах.ПриЗаписи и оттуда обновлять остатки. (в действительности все чуть сложнее, но не суть)

Далее пришли к тому, что из подписки должно вызываться фоновое задание, которое и будет обновлять данные во внешней системе (т.к. это происходит сравнительно долго и не стоит заставлять пользователя ждать)

Но возникла проблема. На момент вызова фонового задания остатки в базе еще не обновлены, соответственно нужно ждать, когда они обновятся.

Но как понять, что они обновились - пока не понятно. Есть идеи?
1 dezss
 
28.05.20
15:49
ИМХО через план обмена.
2 Garykom
 
гуру
28.05.20
16:19
(0) В фоновом сохраняй куда то остатки, затем снимаешь и сравниваешь если есть разница то новые выгружаешь и записываешь вместо старых.
И бесконечный цикл.
3 Garykom
 
гуру
28.05.20
16:20
(2)+ В смысле не обязательно все остатки сохранять а некий хеш, банально общее кол-во например.
4 DrWeb
 
28.05.20
16:27
(1) А чем поможет план обмена? В смысле зарегистрировать изменения, а потом "когда-то" их передать во внешнюю систему? Но задача стоит это делать онлайн. Но чтобы не заставлять ждать пользователя - "псевдо-онлайн". То есть сразу после того, как изменения завершены. Ситуация осложняется еще и тем, что например во время перепроведения документа реализацияТоваровУслуг остатки меняются 4 раза:
1. Удаление движений резервов товаров
2. Удаление движений товаров
3. Создание движений резервов
4. Создание движений товаров.

Сейчас эти изменения накапливаются (в памяти) и осталось их только в нужный момент сбросить во внешнюю систему, но вот как определить "нужный момент"
5 DrWeb
 
28.05.20
16:28
(2) Так примерно и делается. В событиях запоминаются товары по которым происходят изменения. Дальше в "нужный момент" я бы снимал остатки по ним и передавал.
6 DrWeb
 
28.05.20
16:33
(2) Я думал о том чтобы сравнивать, но фоновое задание думаю не обязательно стартует сразу. Так что оно может запуститься в тот момент, когда проведение уже закончилось и отслеживаемые остатки больше меняться не будут.

Пытался делать блокировку проводимого документа в фоновом. Решение хорошее. Типа если удалось заблокировать, значит документ закончил проводиться. Но менеджеры любят по мере набивания большого заказа периодически его проводить не закрывая. Тогда этот документ остается у них заблокированным и не может быть заблокирован в фоновом задании
7 H A D G E H O G s
 
28.05.20
16:34
(0) Сравнить поле Версия Регистратора

    Если ДвижениеМарок<>Неопределено Тогда    
        ОбъектРасширения=АСФРасширенияФункционала.ПолучитьОбъектРасширения();
        Если ОбъектРасширения<>Неопределено Тогда
            КоличествоПопыток=0;
            Пока Истина Цикл
                Попытка
                    Если ОбъектРасширения.Спать(1000)=Ложь Тогда
                        Прервать;
                    КонецЕсли;
                Исключение
                    Прервать;
                КонецПопытки;
                ТекущаяВерсияДанных=АСФОбщегоНазначения.ЗначениеРеквизитаОбъекта(ДвижениеМарок,"ВерсияДанных");
                Если ТекущаяВерсияДанных=НоваяВерсияДанных Тогда //Документ записан, основная транзакция зафиксирована.
                    Прервать;
                КонецЕсли;
                КоличествоПопыток=КоличествоПопыток+1;
                Если КоличествоПопыток>5 Тогда
                    Возврат;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЕсли;
8 H A D G E H O G s
 
28.05.20
16:35
Поле ВерсияДанных
9 DrWeb
 
28.05.20
16:36
Ага, ок, поковыряю. Спасибо
10 H A D G E H O G s
 
28.05.20
16:36
Это, епстественно, в ФоновомЗадании
11 rphosts
 
28.05.20
16:38
(8) +100500 так правильнее чем через сигнальный файл/запись в РС/Константу и т.п.
12 DrWeb
 
28.05.20
16:41
(10) Ну это ясен перец. Не первый день замужем ))
13 Franchiser
 
гуру
28.05.20
16:51
(0) что мешает читать статус из фонового задания?
14 Garykom
 
гуру
28.05.20
16:54
ТС не понимаю.
Остатки надо выгружать только в том случае если они отличаются от прежде выгруженных по некоему расписанию проверяя это.

Если стоит задача асинхронной выгрузки остатков (сразу после изменения) это глупо потому что может никогда не быть достаточного промежутка когда остатки "не меняются"
15 DrWeb
 
28.05.20
16:57
(13) Статус чего?

(14) Речь не о промежутке (типа когда ничего не проводится, тогда и выгружаем). Речь о том, что когда закончил проводиться конкретный документ - выгружаем остатки, на которые он повлиял. Если в это время проводится другой документ влияющий на те же самые остатки - мы их выгрузим еще раз, когда он закончит проводиться
16 Garykom
 
гуру
28.05.20
16:57
(15) Ну так повесь на "после записи" документа запуск фонового
17 Garykom
 
гуру
28.05.20
16:58
(16)+ После записи выполняется при нормальном проведении (не фоновом) после проведения вроде же
18 H A D G E H O G s
 
28.05.20
17:00
Все, что нужно знать о Гарри - вы можете увидеть в (16)
19 Garykom
 
гуру
28.05.20
17:01
(18) Хочешь сказать я не правильно понимаю картинку тут https://its.1c.ru/db/pubdevguide83/content/612/hdoc ?
20 Garykom
 
гуру
28.05.20
17:02
(18) Если это намек что документы могут проводиться массово и обработкой программно то понятно дело надо это учесть чтобы не плодить фоновые
21 H A D G E H O G s
 
28.05.20
17:02
(16) А давай я тебя забаню? Утомительно смотреть на твою чушь.
(19) Да, ты неправильно понимаешь тот момент, когда док может проводиться из формы списка, к примеру.
22 Garykom
 
гуру
28.05.20
17:04
(21) Пруф можно? Насчет формы списка.

ЗЫ Забань мне как раз поработать надо
23 DrWeb
 
28.05.20
17:04
(21)+ Не хочется лазить в документы, думал обойтись событиями
24 H A D G E H O G s
 
28.05.20
17:05
(22) Какой пруф тебе нужен? Что у формы списка нет события ПослеЗаписиНаСервере?
25 Garykom
 
гуру
28.05.20
17:09
26 H A D G E H O G s
 
28.05.20
17:11
(25) Что это?
27 Garykom
 
гуру
28.05.20
17:12
(26) Проведение из формы списка с подпиской на событие ОбработкаПроведения для всех документов
28 H A D G E H O G s
 
28.05.20
17:14
(27) И че, оно ПослеЗаписиНаСервере? Транзакция уже зафиксировалась?
29 Garykom
 
гуру
28.05.20
17:15
(28) А фуй знает, проверять надо.
30 H A D G E H O G s
 
28.05.20
17:16
Давай, Егор, проверяй.
31 DrWeb
 
28.05.20
17:20
Вот тут я ожидаю получить версию данных до того как транзакция зафиксирована

Функция ПолучитьВерсиюДанныхИзБД(Ссылка)
    Запрос = Новый Запрос("ВЫБРАТЬ
                          |    ЗаказПокупателя.ВерсияДанных
                          |ИЗ
                          |    Документ.ЗаказПокупателя КАК ЗаказПокупателя
                          |ГДЕ
                          |    ЗаказПокупателя.Ссылка = &Регистратор");
    Запрос.Параметры.Вставить("Регистратор", Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат Выборка.ВерсияДанных;
    КонецЕсли;
    Возврат Неопределено;
КонецФункции

Но получаю тот же результат, что и НаборЗаписей.Отбор.Регистратор.Значение.ВерсияДанных
32 dezss
 
28.05.20
17:24
(31) Да конечно будет то же самое, запись в базу же уже произошла.
Я чет только теперь понял, что у тебя просто остатки еще не пересчитались в (0).
Движения есть, а остатки пока еще не актуальные.
А вот когда они пересчитываются и в этой ли транзакции, тут хз, если честно.
ИМХО, в фоновом брать остатки перед этими движениями и накатывать движения этого набора записей ручками.
33 dezss
 
28.05.20
17:25
(32) + Правда будет проблема, если тут транзакция откатится, а данные во внешнюю уже ушли.
34 DrWeb
 
28.05.20
17:28
(32) Запись то произошла, но транзакция еще не... А стоп. Ща попробую из фонового.. Это ж я из одного сеанса пробую. Понятно, что будет одно и то же.
35 fisher
 
28.05.20
17:29
Вопрос - как в фоновом понять что проведение сбойнуло, транзакцию откатило и ждать более не стоит.
А для "ожидания" фонового я бы задействовал не ожидание в самом фоновом, а повтор выполнения фонового по таймауту. Там же штатно можно и количество повторов ограничить.
Но мне кажется, что все это горе от ума и достаточно будет "псевдоонлайна". Например, ежеминутного.
36 H A D G E H O G s
 
28.05.20
17:30
(34) Тебе в Фоновое надо передать версиюданных из ПриЗаписи(), из основной транзакции, когда она будет уже обновленной.
И в фоновом ждать, когда же в БД обновиться ВерсияДанных, сравнивая ее с переданной.
37 fisher
 
28.05.20
17:32
Недавно попал на неприятную штуку при "онлайн-синхронизации" (распределенная транзакция между 1С и внешней системой). Транзакция во внешней системе фиксировалась в конце обработки проведения в 1С.
А потом выяснилось, что в одной из подписок писался еще регистр. И когда он падал на блокировках, то ой...
38 H A D G E H O G s
 
28.05.20
17:36
(37) НаборЗаписей.Записать(Истина) - источник нехилых проблем.
39 DrWeb
 
28.05.20
17:40
(36), да, так и делаю. Вроде это решает проблему. Единственное при откате фоновое не дождется, но это вроде решается установкой таймаута на время заведомо большее, чем время проведения документа.

Спасибо!
40 mistеr
 
28.05.20
17:53
(0) >Необходимо сделать онлайн обновление остатков во внешней системе

Я бы посоветовал забыть про "онлайн", его все равно не добиться.
Вместо этого изучить исходную проблему и найти более вменяемое решение, чем "онлайн остатки".
41 DrWeb
 
28.05.20
23:55
(40) Онлайн - не с целью загрузить вычислительные мощности побольше. А скорее наоборот с целью не делать обмен раз в минуту например, когда основное время в базе ничего не происходит. Но есть пара часов, когда происходит интенсивно и тогда надо чтобы обновлялось как можно быстрее
42 fisher
 
29.05.20
09:10
(41) > Онлайн - не с целью загрузить вычислительные мощности побольше. А скорее наоборот с целью не делать обмен раз в минуту например, когда основное время в базе ничего не происходит.
Тогда, ИМХО, ты зря так делаешь. Если проверки очень легкие, то никакой проблемы делать их ежеминутно или даже чаще - нет. В то время как запускать из транзакции фоновое задание без особой необходимости не кажется мне замечательным со всех сторон решением. Особенно при пакетных проведениях.
43 DrWeb
 
29.05.20
09:34
(42) Ну можно отслеживать групповую обработку и ожидать ее завершения. Тут еще политика вмешивается. Клиент хочет "онлайн". На вопрос как часто мы должны обновлять информацию во внешней системе ответ: Она там должна быть актуальной ВСЕГДА )))
Ну хрен с вами, любой каприз за ваши деньги
44 Cyberhawk
 
29.05.20
09:46
(43) Поставь расписание каждые 5 секунд и успокойся
45 fisher
 
29.05.20
09:55
(43) Это стандартный ответ заказчика, не осознающего всех плюсов-минусов. Для него вопрос "выбирайте - онлайн или по расписанию" звучит как "выбирайте - хорошо или плохо". Ясен пень, он хочет "онлайн", даже если на самом деле настоящий онлайн ему абсолютно некритичен. Заказчики вообще в подавляющем большинстве случаев не представляют сложностей взаимодействия систем. Для них это естественная магия. Оно должно "само и сразу, а разве иначе бывает?". Тут уже умение донести.
46 mzelensky
 
29.05.20
10:01
(0) "Тут еще политика вмешивается. Клиент хочет "онлайн". Она там должна быть актуальной ВСЕГДА" - а запаздывание в 5 секунд это ВСЕГДА? а в 1 секунду? в 0,5 секунды это ВСЕГДА?

Не парь себе мозги. Делай через регламент
47 fisher
 
29.05.20
10:07
(46) КАК ТЫ НЕ ПОНИМАЕШЬ! ЗАПАЗДЫВАНИЯ БЫТЬ НЕ ДОЛЖНО! НЕУЖЕЛИ СЛОЖНО СДЕЛАТЬ ЧТОБЫ СРАЗУ? СМОТРИ - ВОТ ЭТИ ЦИФИРКИ ДОЛЖНЫ ПОМЕНЯТЬСЯ ОДНОВРЕМЕННО! ДАЖЕ ЗВУЧИТ ПРОСТО И ПОНЯТНО, РЕБЕНОК ПОЙМЕТ! НЕ НАДО НИЧЕГО УСЛОЖНЯТЬ КАКИМИ-ТО "РЕГЛАМЕНТАМИ"! ПОНАПРИДУМЫВАЮТ ЖЕ! ВЕЧНО ЭТИ ПРОГРАММИСТЫ ВСЕ УСЛОЖНЯЮТ! ЛИШЬ БЫ ДЕНЕГ ПОБОЛЬШЕ СОДРАТЬ!
48 Cyberhawk
 
29.05.20
10:10
Там подготовка данных для отправки и коннект к получателю скорее всего 1-5 секунд будет происходить, так что никаких проблем поставить регламент 5 секунд нет.
Для особо взыскательных - хоть каждую секунду, все равно пока не отработал один такт следующий не начинается, если конечно такт РЗ не используется как менеджер побочных ФЗ. Тогда надо реализовывать еще и механизм как попридержать коней.
49 mzelensky
 
29.05.20
10:18
(41) Учитывая это:

"Но есть пара часов, когда происходит интенсивно и тогда надо чтобы обновлялось как можно быстрее"

я бы скорее задумался о настройке, по которой система будет автоматически менять частоту рег. задания в течении дня. Т.е. рег. задание, которое будет менять настройки другого рег.задания. Допустим (чисто пример):

с 0 утра (ночи) до 12 дня частота 1 минута
с 12 дня до 16 дня частота 5 секунд
с 16 дня до 0 ночи частота 30 секунд

Но вообще можно даже с этим не заморачиваться и просто ставить 1 минуту.
50 mistеr
 
29.05.20
11:07
(43) >Тут еще политика вмешивается. Клиент хочет "онлайн".
>Ну хрен с вами, любой каприз за ваши деньги

Как ты не понимаешь, когда ты не обеспечишь ему этот каприз, ты будешь крайним, а не кто-то.

Если те не докопался до исходной проблемы (зачем вообще там остатки), ты не выполнил свою работу как спец по автоматизации.
51 BeerHelpsMeWin
 
29.05.20
11:12
(0) А внешняя система сама не может при необходимости обращаться к 1с(допустим, к веб-сервису) за актуальными остатками на именно нужную номенклатуру?
Я так понимаю, где-то на сайте идет какой-то заказ товара, и нужно проверить наличие остатков в момент нажатия на кнопку "заказать товар"?
52 fisher
 
29.05.20
12:15
(51) Тут такое дело, что "заминка" при заказе крайне нежелательна. Клиент должен расставаться с деньгами легко и быстро. И временные перебои в работе связки систем не должны останавливать поток бабла и портить впечатления покупателей от чудесного сервиса.
Плюс список остатков обычно тоже нужен. Можно было бы, конечно, дергать одинэсный сервис для этого. Но кэширование и обновление кэша  все равно понадобится. А значит - что в лоб, что по лбу. Либо с той стороны регламент, либо с этой. Тут уже по обстоятельствам. Другое дело, что можно оптимизировать выгрузку/загрузку. И гонять только изменившиеся позиции. Но это усложнение тоже не дармовое. Так что я бы стал с этим заморачиваться только если полная выгрузка остатков начнет создавать проблемы. Но это только на огромном ассортименте случится.
53 Cyberhawk
 
29.05.20
17:49
(52) Точные остатки по большому счету не нужны, достаточно вообще троичного "много - средне - мало" показывать клиенту на сайте. Ситуация, когда он заказывал, и оно закончилось - в порядке вещей.
Так что эти онлайн-остатки в 99% просто блажь.
54 fisher
 
29.05.20
17:53
(53) Это в B2C может быть так. А в B2B сплошь и рядом все не так просто.
55 mistеr
 
29.05.20
19:20
(53) +100
56 Cyberhawk
 
29.05.20
19:56
(54) А если нужно гарантированное резервирование, то и там никакой онлайн не поможет - один фиг бронь будет применяться и конкуренция будет происходить непосредственно в момент дерганья сервиса отправки заказа и отлуп тоже возможен