Удав написал(а):
отправлять IDOC после обработки всех входящих IDOC.
Ключевое слово здесь - после. Отправлять IDOC после того, как убедились, что изменения действительно сохранены в БД, а не после того, как вызвали БАПИ и сделали коммит.
Я видимо как-то неудачно объяснил, что ли.
В коде это выглядит примерно так:
Code:
FUNCTION PROCESS_IDOC_ZMYTYPE_IN. "процессор входящего айдока
бла бла бла
CALL FUNCTION 'BAPI_CHANGE_OUTBOUND_DELIVERY'. - изменения будут записаны в ДБ в ходе отработки V2 UPDATE TASK-а
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
WAIT = 'X'.
подготовить структуру NAST
CALL FUNCTION 'RV_MESSAGE_UPDATE'. - отправка исходящего айдока, сработает сразу же
выдрать из RSNASTED полученный EDIDC-DOCNUM и записать его в лог для входящего айдока
ENDFUNCTION.
То есть, нет гарантии что к тому моменту как RV_MESSAGE_UPDATE (он добавляет OUTPUT TYPE задекларированный как EDI и собственно через это и генерируется исходящий айдок) начнет работу, изменения будут уже в ДБ (напоминаю, ФМ с отложенным стартом V2 не сработают сразу после ждущего коммита как это делают V1). На практике это все происходит все равно очень быстро, но чисто теоретический шанс остается, что низкоприоритный V2 протормозит и RV_MESSAGE_UPDATE уйдет раньше. Случай из жизни - чинил программу, в которой индусы делали Post Goods Issue и сразу же отправляли IDOC. IDOC смотрел значение LIKP-WADAT_IST, не находил его, считал что PGI не сделано и отменял отправку.
Чтобы такая гарантия была, надо чтобы RV_MESSAGE_UPDATE тоже выполнился с отложенным стартом из V2, но вот получить заветный номер и кинуть его в лог для входящего айдока - мол, юзер наш дорогой, смотри и радуйся, мы отпроцессили входящий документ, и отправили в обратку другой с номером таким-то - при таких раскладах не получится.
А все потому, что 'BAPI_CHANGE_OUTBOUND_DELIVERY' вызывает для записи в ДБ ФМ LIEFERUNG_WRITE_DOCUMENT, которую сумрачный тевтонский гений зачем-то оформил как V2 a не V1.
Все это можно решить, если заменить CALL FUNCTION 'BAPI_CHANGE_OUTBOUND_DELIVERY' на тупо UPDATE likp SET zfield = my_value WHERE vbeln = my_vbeln. Какие риски можно поиметь в таком случае, кроме утраты репутации?
Как вариант, можно поставить цикл с таймером - проверять через каждые 5 секунд, не записались ли наконец заветное значение в LIKP-ZFIELD, но это выглядит еще ужаснее чем UPDATE LIKP