Текущее время: Сб, июл 19 2025, 01:01

Часовой пояс: 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 часа


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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