Jak uruchomić moduł funkcyjny w tle z COMMIT?

Jeśli programujesz, administrujesz, integrujesz i masz wątpliwość lub obawę, to właśnie najlepsze miejsce dla Ciebie. Pisz śmiało...
wojtas7
Posty: 1056
Rejestracja: pt mar 14, 2008 12:51 pm
Has thanked: 71 times
Been thanked: 313 times

Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: wojtas7 »

Mam następującą zagwozdkę: potrzeba na skanerze w EWM (kod skanerowy całkiem zetowy) założyć oraz spakować sporą ilość HUsów:

-> najpierw zakładamy HU -> klasa /SCWM/CL_WM_PACKING->/scwm/if_pack_bas~create_hu
-> musi być COMMIT WORK żeby HU był w bazie aby go spakować:

-> odpalamy moduł do zadania magazynowego do spakowania tego HU /SCWM/TO_CREATE i dajemy IV_COMMIT_WORK = TRUE

-> w przypadku gdy nie uda się spakować, jest ROLLBACK oraz usunięcie stworzonego HU i kolejny COMMIT.

Problem jest taki że taka konstrukcja dla >100 HUsów trwa długo i po ~20s skaner jako że przeglądarkowy jest to wyświetla TIME OUT.

Czy da się przerzucić ten kod do osobnego LUW w update tasku, na przykład CALL FUNCTION func IN BACKGROUND TASK [AS SEPARATE UNIT]?
Będzie problem bo wewnątrz nie można dawać COMMIT:

https://help.sap.com/doc/abapdocu_751_i ... d_task.htm

The statements COMMIT WORK and ROLLBACK WORK must not be executed within a LUW. In addition, no implicit database commit can be triggered there.
wojtas7
Posty: 1056
Rejestracja: pt mar 14, 2008 12:51 pm
Has thanked: 71 times
Been thanked: 313 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: wojtas7 »

Ogarnąłęm temat w taki sposób, wydaje mi się że ciekawe :-)

Kod: Zaznacz cały

  WHILE lb_continue = abap_true.        " call FuBa in packs of 10 HUs + rest

    CLEAR lv_task.
    lv_task = 'ZFUBA.
    lv_numer = sy-index. CONDENSE lv_numer.
    CONCATENATE lv_task lv_numer INTO lv_task.  " unique task name

    CALL FUNCTION 'ZFUBA' STARTING NEW TASK lv_task
      PERFORMING end ON END OF TASK
      EXPORTING
        is_com   = is_com
        iv_no_hu = lv_no_of_hus_now.    " how many HUs create+pack

  ENDWHILE.

  WAIT FOR ASYNCHRONOUS TASKS UNTIL g_separatetask_number EQ lv_no_of_hus_orig.

  es_com       = gs_com.
  ev_error     = gv_error.
  et_bapiret[] = gt_bapiret[].
  ev_errno     = gv_errno.

  es_com-technical-grinbdel-t_huident[] = gt_hus[].  " all created HUs taken from FROM end

ENDFUNCTION.


FORM end USING taskname.

  DATA: ls_com     TYPE  zlmob_com_struct,
        lv_error   TYPE  zlflag_abap_true_false,
        lt_bapiret TYPE  bapirettab,
        lv_errno   TYPE  zlmsb_errno,
        lv_no_hu   TYPE int4.

  CLEAR: ls_com, lv_error,  lv_errno.
  FREE: lt_bapiret.

  RECEIVE RESULTS FROM FUNCTION 'ZFUBA'
    IMPORTING
       es_com     = ls_com
       ev_error   = lv_error
       et_bapiret = lt_bapiret
       ev_errno   = lv_errno
       ev_no_hu   = lv_no_hu.    " how many HUs create+pack in this FuBa call

  ADD lv_no_hu TO g_separatetask_number.                          " number of HU created

  " returned data
  APPEND LINES OF ls_com-technical-grinbdel-t_huident TO gt_hus.  " created HU
  gs_com       = ls_com.
  gv_error     = lv_error.
  gt_bapiret[] = lt_bapiret[].
  gv_errno     = lv_errno.

ENDFORM.

Ciekawe jest w obrębie tej grupy funkcyjnej operuję na danych globalnych, i wpisuję tam stworzone HU w każdym z wątków osobnych LUW, i sumuję ilość HU żeby czekał program aż wszystkie wątki się skończą. W ten sposób skaner sobie czeka i trwa to dla 100 HU około 20s zamiast 3:30 minuty. Dałem na razie paczki po 10 HU do stworzenia i spakowania, ciekawe jak wypadną testy.
dominik.tylczynski
Posty: 8289
Rejestracja: wt kwie 03, 2007 4:05 pm
Has thanked: 1903 times
Been thanked: 1470 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: dominik.tylczynski »

Ciekawe podejście. Zauważ, że w ten sposób zrównoleglasz pracę i wykorzystujesz kilka procesów dialogowych. Jeśli się rozpędzisz to możesz zająć wszystkie procesy i wtedy inni użytkownicy będą mieli problem z dostępem do systemu.
dominik.tylczynski
Posty: 8289
Rejestracja: wt kwie 03, 2007 4:05 pm
Has thanked: 1903 times
Been thanked: 1470 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: dominik.tylczynski »

wojtas7 pisze: wt gru 12, 2023 8:27 am Mam następującą zagwozdkę: potrzeba na skanerze w EWM (kod skanerowy całkiem zetowy) założyć oraz spakować sporą ilość HUsów:

-> najpierw zakładamy HU -> klasa /SCWM/CL_WM_PACKING->/scwm/if_pack_bas~create_hu
-> musi być COMMIT WORK żeby HU był w bazie aby go spakować:

-> odpalamy moduł do zadania magazynowego do spakowania tego HU /SCWM/TO_CREATE i dajemy IV_COMMIT_WORK = TRUE

-> w przypadku gdy nie uda się spakować, jest ROLLBACK oraz usunięcie stworzonego HU i kolejny COMMIT.

Problem jest taki że taka konstrukcja dla >100 HUsów trwa długo i po ~20s skaner jako że przeglądarkowy jest to wyświetla TIME OUT.
Przyznam, że nie do końca rozumiem jak wygląda realna praca magazyniera z tą transakcją.
Zwykle budowałem transakcje RF, tak aby odzwierciedlały maksymalnie to co faktycznie/realnie robi magazynier oraz aby postęp pracy magazyniera był na bieżąco zapisywany w systemie, tak aby nic nie stracić w przypadku np. zerwania sesji skanera czy padu baterii.

Czy faktycznie w Twoim procesie jednocześnie magazynier pakuje ponad 100 HUs? Jeśli je pakuje pojedynczo, to może warto od razu, zapisywać dane w EWM po spakowaniu każdej HU? To powinno iść dużo szybciej.
yacol
Posty: 561
Rejestracja: śr kwie 04, 2007 4:32 pm
Lokalizacja: Poznań
Has thanked: 9 times
Been thanked: 165 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: yacol »

Też chciałem zaproponować aRFC w jej wersji równoległej pRFC: https://help.sap.com/docs/SAP_NETWEAVER ... 2189b.html

bo sam kiedyś dzięki rozwiązaniom opisanym

np. tu: https://blogs.sap.com/2019/03/19/parall ... made-easy/

albo tu: https://blogs.sap.com/2019/03/13/and-no ... rocessing/

rozwaliłem tematy trudne do ogarnięcia przez podejście nazwijmy to "jednowątkowe".

I mała łyżka dziegciu do beczki miodu: niestety czasy wykonania równoległego zależą od kilku czynników np. obciążenia systemu, ilości sesji już działających, itd. więc ostatecznie może dojść do sytuacji gdzie przekroczone zostanie 20s i problem powróci. Nie znam szczegółów technicznych Twojego rozwiązania, ale też popełniłem w życiu trochę przeglądarkowych transakcji skanerowych (niektóre zresztą razem z Dominikiem :)) i jeszcze bym pomyślał o tym czy jest możliwość ustawienia wartości timeout'u na samym skanerze (w przeglądarce) na taką wartość żeby po prostu czekał na odpowiedź serwera do "usranej śmierci".
Pozdrawiam,

Jacek Witczak
http://novertio.pl
K602
Posty: 132
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: K602 »

Od siebie dorzucę jeszcze, że do zrównoleglania procesów, warto użyć SPTA Framework...
SAP ABAP Certified Developer
dominik.tylczynski
Posty: 8289
Rejestracja: wt kwie 03, 2007 4:05 pm
Has thanked: 1903 times
Been thanked: 1470 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: dominik.tylczynski »

Ja chyba jednak bym nie robił tutaj przetwarzania równoległego. Moim zdaniem problem nie polega na tym, że pakowanie >100 HUs trwa zbyt długo, tylko że to pakowanie jest robione online i magazynier musi czekać aż całość zostanie przetworzona, a dodatkowo może się nie doczekać i dostać time out.
Sądzę, że lepiej byłoby wyrzucić pakowanie HUs poza przetwarzanie dialogowe, coś na zasadzie update task. Oczywiście update tasks nie można tutaj wykorzystać, bo spakowanie jednej HU to kilka operacji z oddzielnymi COMMIT.
Można by natomiast wrzucić pakowanie każdej HU w oddzielną kolejkę qRFC lub bgRFC i do każdej tej kolejki wstawić poszczególne kroki dla danej jednostki tj.
  • tworzenie - /SCWM/CL_WM_PACKING->/scwm/if_pack_bas~create_hu
  • spakowanie - /SCWM/TO_CREATE
  • sprawdzenie pakowania i ewentualne usunięcie jednostki
Samo utworzenie kolejek RFC pójdzie bardzo szybko. Po ich utworzeniu można oddać ekran magazynierowi - niech pracuje dalej, a te kolejki się spokojnie przetworzą.
yacol
Posty: 561
Rejestracja: śr kwie 04, 2007 4:32 pm
Lokalizacja: Poznań
Has thanked: 9 times
Been thanked: 165 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: yacol »

I wszystko jasne :)
Pozdrawiam,

Jacek Witczak
http://novertio.pl
wojtas7
Posty: 1056
Rejestracja: pt mar 14, 2008 12:51 pm
Has thanked: 71 times
Been thanked: 313 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: wojtas7 »

Dzięki, wydaje mi się że jednak te wątki równoległe (w najgorszym przypadku kilkanaście dodatkowych wątków), będą niezbędne:

Proces na skanerze wygląda tak:

- przyjeżdża tir ze 100 paletami od dostawcy z zewnątrz, wszystkie sto palet mają taką samą ilość tego samego towaru

- magazynier ma dostawę przychodzącą na ten towar w referencji do zamówienia, wpisuje numer dostawy przychodzącej, wpisuje 100 palet, każda po np. 10 sztuk. Skaner tworzy 100 HU, pakuje 100 te HU po 10 sztuk produktu, pojawia się kolejny ekran z przyciskiem "Magazynuj", który tworzy 100 zleceń/zadań magazynowych na zmagazynowanie fizyczne w magazynie tych 100 palet - drukarka drukuje z PPF formularz /scwm/wo_single, magazynierzy rozklejają etykiety na te 100 palet i wózkowi rozwożą je po magazynie.

Także najtrudniejsze tu było, aby magazynier widział na ekranie że te 100 HU palet jest założone prawidłowo, i może nacisnąć kolejny przycisk do zmagazynowania fizycznego.

Także opcje każdego HU osobno do qRFC odpada, magazynier musi widzieć że wszystkie są już w systemie.
dominik.tylczynski
Posty: 8289
Rejestracja: wt kwie 03, 2007 4:05 pm
Has thanked: 1903 times
Been thanked: 1470 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: dominik.tylczynski »

wojtas7 pisze: czw gru 14, 2023 11:31 am Dzięki, wydaje mi się że jednak te wątki równoległe (w najgorszym przypadku kilkanaście dodatkowych wątków), będą niezbędne:
Skoro jedna idziesz w przetwarzanie równoległe to zobacz artykuł Using class CL_ABAP_PARALLEL for mass parallel dialog work processes
Może Ci to ułatwi implementację.
yacol
Posty: 561
Rejestracja: śr kwie 04, 2007 4:32 pm
Lokalizacja: Poznań
Has thanked: 9 times
Been thanked: 165 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: yacol »

W mojej wersji systemu (7.56) jest też przykładowy program: RS_ABAP_PARALLEL_EXAMPLE.
Nooo i jeszcze jedno - w linku podanym przez Dominika wreszcie nie ma w kodzie ABAP (zparallel_test) szkodnika o nazwie notacja węgierska :D
Pozdrawiam,

Jacek Witczak
http://novertio.pl
K602
Posty: 132
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: K602 »

W przeciwieństwie do wspomnianego przeze mnie SPTA, to jest obiektowe ;)
SAP ABAP Certified Developer
K602
Posty: 132
Rejestracja: śr sie 24, 2022 11:50 am
Has thanked: 60 times
Been thanked: 86 times

Re: Jak uruchomić moduł funkcyjny w tle z COMMIT?

Post autor: K602 »

yacol pisze: pn gru 18, 2023 2:21 pm W mojej wersji systemu (7.56) jest też przykładowy program: RS_ABAP_PARALLEL_EXAMPLE.
Nooo i jeszcze jedno - w linku podanym przez Dominika wreszcie nie ma w kodzie ABAP (zparallel_test) szkodnika o nazwie notacja węgierska :D
Napisałem PW :) W 7.50 nie ma...
SAP ABAP Certified Developer