Текущее время: Пт, июл 18 2025, 18:49

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
 Заголовок сообщения: запуск BAPI in LOOP and save all with ONE COMMIT
СообщениеДобавлено: Ср, янв 15 2014, 08:14 
Начинающий
Начинающий

Зарегистрирован:
Ср, дек 19 2012, 18:35
Сообщения: 5
Идея следующая (можно пропустить):
Есть транзакция, в которой делается проводка (MIRO). И для каждой позиции документа необходимо создать подтверждение с помощью BAPI (BAPI_NETWORK_CONF_ADD - на вход нужен номер сетевого графика, а он у позиций может быть разный). Мы создали реализацию BADI метод CHANGE_AT_SAVE, где и пытаемся вызвать BAPI несколько раз. И нужно сделать так, чтобы проводка и все запуски BAPI проводились в БД либо вместе, либо вместе откатывались.

1) Соответственно вставить 'BAPI_TRANSACTION_COMMIT' нельзя, т.к. нарушится целостность данных и при COMMIT WORK в самой транзакции - получаем DUMP. Кроме того мы не сможем в таком случае сохранять и откатывать все данные вместе.
2) Если 'BAPI_TRANSACTION_COMMIT' - не вставлять вообще, чтобы все сохранения выполнились по COMMIT WORK в самой транзакции - то все работает, если BAPI запускается только один раз. Но позиции могут принадлежать разным сетевым графикам, поэтому запускать BAPI нужно несколько раз. А при повторном запуске BAPI в ней возникает неконсистентность и она выдает ошибку - из-за того, что два запуска BAPI делаются в рамках одного LUW

Проблема
Получается, что мы имеем примерно следующее

* наше расширение
Code:
LOOP

     CALL BAPI   " BAPI_NETWORK_CONF_ADD - но не важно какую BAPI запускать
                  " при втором проходе цикла BAPI - выдает ошибку из-за того, что LUW остался прежним.
                  " вставить BAPI_TRANSACTION_COMMIT в цикл нельзя т.к. будет дамп (расш. в момент сохранения - нарушается целостность данных  самой ТА)
                  " и кроме того не будет возможности все откатить в случае, если стандарт выйдет на ROLLBACK или же откатить предыдущие BAPI в  случае 
                  " ошибки в одной из них
ENDLOOP.


* далее где-то в стандарте
Code:
COMMIT WORK.


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


На данный момент реализовал так - но это не правильно
* наше расширение
Code:
LOOP

     CALL FUNCTION 'BAPI*' DESTINATION 'NONE' .
     * если ошибок нет
     CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' DESTINATION 'NONE' .
     CALL FUNCTION 'RFC_CONNECTION_CLOSE' EXPORTING DESTINATION 'NONE' .
    * если ошибки есть
     CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK' DESTINATION 'NONE' .
     CALL FUNCTION 'RFC_CONNECTION_CLOSE' EXPORTING DESTINATION 'NONE' .
                             " соответственно сохраняем все запуски BAPI независимо друг от друга в отдельных режимах - чтобы не нарушать целостность LUW   
                               самой транзакции, но сделать так, чтобы СОХРАНИТЬ ВСЕ ИЛИ НИЧЕГО не удается
ENDLOOP.


* далее где-то в стандарте
Code:
COMMIT WORK.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: запуск BAPI in LOOP and save all with ONE COMMIT
СообщениеДобавлено: Ср, янв 15 2014, 09:48 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Пт, сен 23 2005, 11:11
Сообщения: 963
обычно не получается чередовать вызовы bapi в одном sap luw,
т.к. контекст один и тот же, и в очередь задачи обновления копятся все запуски,
это не гарантирует целостность данных.

можно попробовать такой вариант:
какая именно bapi функция? поищите параметр тестового запуска, либо используйте откат (rollback):
запускаете bapi по очереди, лучше в другой задаче (напр: завернуть в ф/м и его запускать в нужной задаче),
с откатом в каждой итерации, при условии, что запуск очередной bapi не зависит от результатов
работы предыдущей итерации. накопленные сообщения проверяете на критичность.
если ошибок по списку нет - запускаете ,лучше в другой задаче, с commit в каждой итерации.

главное не затронуть sap luw текущей транзакции.
в любом случае, остаётся вариант со сторнированием проведённого при появлении первой ошибки


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: запуск BAPI in LOOP and save all with ONE COMMIT
СообщениеДобавлено: Ср, янв 15 2014, 10:37 
Начинающий
Начинающий

Зарегистрирован:
Ср, дек 19 2012, 18:35
Сообщения: 5
trop - спасибо, коллеги также сказали, что именно как я хотел - реализовать нельзя.
BAPI которую я использую - BAPI_NETWORK_CONF_ADD в ней есть testrun.

Сейчас сделал следующим образом:

Code:
* наше расширение BADI
Код:
LOOP
     CALL FUNCTION 'BAPI_NETWORK_CONF_ADD'   " тестовый режим
          EXPORTING
               TEST_RUN = 'X'.
          IMPORTING
               return  =  ls_return.
   
    IF ls_return IS INITIAL.  " если ошибок нет
        CALL FUNCTION 'Z_BAPI_RUN' IN UPDATE TESK.       
    ELSE.
        ROLLBACK WORK.
        MESSAGE 'Ошибка' TYPE 'E'.
    ENDIF.
ENDLOOP.
------------------------------------------------

* далее где-то в стандарте
Код:
COMMIT WORK. или ROLLBACK
------------------------------------------------

* ФМ Z_BAPI_RUN  (модуль обновления "Немедленный запуск")
код:
CALL FUNCTION 'BAPI_NETWORK_CONF_ADD' DESTINATION 'NONE' .
      IMPORTING
          return  =  ls_return.
   
IF ls_return IS INITIAL.  " если ошибок нет
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' DESTINATION 'NONE' .
    CALL FUNCTION 'RFC_CONNECTION_CLOSE' EXPORTING DESTINATION 'NONE' .
ELSE.   " если ошибки есть
   CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK' DESTINATION 'NONE' .
   CALL FUNCTION 'RFC_CONNECTION_CLOSE' EXPORTING DESTINATION 'NONE' .
ENDIF.

(код проверен - работает)

Таким образом, все мои запуски BAPI проверяются в тестовом режиме и если хоть один с ошибкой - прерываю всю работу.
Если ошибок нет и стандарт дошел до COMMIT WORK - запустятся все мои модули обновления и все BAPI сохранятся.
Но что делать, если вдруг BAPI в тестовом режиме выполнилась успешно, а уже при commit в модуле обновления возникла ошибка?
Как тогда откатывать все изменения.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: запуск BAPI in LOOP and save all with ONE COMMIT  Тема решена
СообщениеДобавлено: Ср, янв 15 2014, 12:29 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Пт, сен 23 2005, 11:11
Сообщения: 963
с этой bapi не работал, для отката при ошибках в другой задаче нужно найти bapi удаления(сторно|reverse)
если есть или написать пакетник для отмены
Code:
в расширении (badi):

loop
  call function BAPI_NETWORK_CONF_ADD test_run = X
  return -> return_all
* rollback не запускаем, тк находимся в luw транзакции (нельзя завершать luw, тк это отменит задачу update)
* commit тоже не запускаем, тк он запустит задачу update преждевременно
endloop

loop at return_all  where type ca 'EAX'
  error = X
endloop
if error = space
  call function Z_BAPI_RUN
    destination NONE или IN BACKGROUND TASK 
   (чтобы можно было безопасно использовать операторы commit,rollback)
*{ внутри функции:
  loop
    call function BAPI_NETWORK_CONF_ADD test_run = space
    if bapi_error = X
      rollback work
      loop document_log
        reverse document bapi
        commit work
      endloop
      exit
    else
      document_number -> document_log
      commit work
    endif
  endloop
*} внутри функции

else
  сообщить об ошибке <- return_all
endif


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: запуск BAPI in LOOP and save all with ONE COMMIT
СообщениеДобавлено: Ср, янв 15 2014, 14:30 
Начинающий
Начинающий

Зарегистрирован:
Ср, дек 19 2012, 18:35
Сообщения: 5
Да, то, что нужно делать сторно - это понятно, но нужно собирать номера ранее созданных документов.
Для этого можно создать в группе функций (для ФМ 'Z_BAPI_RUN') глобальную табличку и там сохранять номера, а затем в случае ошибки откатить с помощью BAPI_NETWORK_CONF_CANCEL.

Но в итоге мы с постановщиком сошлись на том, что если стандартная ТА выполнится успешно и будет commit - то и мы создаем документ "подтверждения" с помощью BAPI_NETWORK_CONF_ADD - причем, если вдруг не создалось "подтверждение" - то достаточно записать информацию в какой-нибудь лог. Главное, чтобы не было того, чтобы BAPI-ки создавали документы "подтверждения", если сама проводка в транзакции MIRO - не будет создана (т.е. будет ROLLBACK). А это уже предусмотрено в моем вышеописанном алгоритме.

Спасибо, Тему можно считать закрытой.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB