İçeriğe geç

ABAP Cloud'da Arka Plan İşleri: Application Jobs ve bgPF — Hangisi Ne Zaman?

Klasik ABAP'ta arka plan işi bir rapor, bir varyant ve SM36 demekti. ABAP Cloud'da bu yolların yerini iki araç alıyor: planlı işler için Application Jobs, bir kayıttan sonra arka planda çalışması gereken adımlar için bgPF. İkisinin farkını, kurulumunu ve en sık yapılan hataları anlatıyorum.

Mustafa Önder Mustafa Önder  ·  19 Ekim 2026  ·  17 dk okuma

İçindekiler

  1. SM36 ve SUBMIT Neden Yetmiyor?
  2. Karar Tablosu
  3. Application Jobs: Dört Parça
  4. İş Sınıfı ve Parametreler
  5. Hata ve Günlük
  6. İşi Koddan Planlamak
  7. bgPF: Kayıttan Sonra Arka Planda
  8. bgPF'yi RAP'ten Başlatmak
  9. bgPF'yi İzlemek
  10. Tasarım Önerileri
  11. Sık Yapılan Hatalar
  12. Sonuç

Bir ABAP geliştiricisine "bu iş gece çalışsın" dediğinizde verdiği cevap yıllarca aynıydı: bir rapor yazılır, seçim ekranına varyant kaydedilir, SM36'da iş planlanır, sonuç SM37'de izlenir. Kayıttan sonra çalışması gereken yan işler için ise CALL FUNCTION ... IN BACKGROUND TASK ya da STARTING NEW TASK kullanılırdı.

ABAP Cloud dil sürümünde bu yolların çoğu serbest bırakılmış (released) API değildir. Yerine iki ayrı araç gelir ve en önemli tasarım kararı, işin hangisine ait olduğunu doğru seçmektir. Bu yazıdaki arayüz, sınıf ve metot adları SAP'nin BTP ABAP ortamı belgelerine ve resmi ABAP cheat sheet deposuna dayanır; bu API'ler sürümler arasında gelişmeye devam ettiği için sisteminizdeki sürümün belgesini de kontrol edin.

SM36 ve SUBMIT Neden Yetmiyor?

On-premise S/4HANA'da klasik ABAP ile yazılmış kod için SM36 hâlâ çalışır. Sorun, clean core yaklaşımında yeni geliştirmenin ABAP Cloud kurallarıyla yazılmasıdır: o kodda rapor, SUBMIT ve klasik iş planlama fonksiyonları kullanılamaz. Bu bir kısıtlamadan çok bir ayrımdır:

  • Planlı iş bir takvime, bir seçim ekranına ve bir izleme ekranına ihtiyaç duyar: "Her gece 02:00'de onaylı masraf formlarını aktar."
  • Asenkron adım bir işlemin parçasıdır ve o işlem başarılı olursa çalışmalıdır: "Form onaylandığında, kullanıcıyı bekletmeden bildirimi gönder."

Klasik dünyada ikisi de çoğu zaman aynı araçla, bir arka plan işiyle çözülürdü. ABAP Cloud'da bunlar iki ayrı araçtır.

Karar Tablosu

Application Jobs ile bgPF karşılaştırması
KonuApplication JobsbgPF
Ne başlatır?Takvim, kullanıcı ("Application Jobs" uygulaması) veya APIBir işlemin COMMIT WORK'ü
Ne zaman çalışır?Planlanan zamanda; tek seferlik veya periyodikİşlem kaydedildikten sonra, kuyruğa alınarak; bir kez
ParametreSeçim ekranı (sınıfın public öznitelikleri) ve şablonOperasyon nesnesinin öznitelikleri (kodda verilir)
İşlem bütünlüğüİş kendi başına bir işlemdirBaşlatan işleme bağlıdır: geri alınırsa süreç başlamaz
İzlemeApplication Jobs uygulaması ve işe bağlı uygulama günlüğüSüreç monitörü nesnesi ve bgRFC izleme araçları
Tipik işGece aktarımı, toplu düzeltme, periyodik temizlikKayıttan sonra bildirim, belge üretimi, yavaş bir yan iş
Kısa kural: İş birinin takviminde görünmesi gereken bir şeyse Application Jobs; bir kullanıcı işleminin kullanıcıyı bekletmemesi gereken devamıysa bgPF.

Application Jobs: Dört Parça

Bir application job dört nesneden oluşur:

  1. İş sınıfı: Çalışacak kod. Yeni geliştirmeler için IF_APJ_RT_RUN arayüzü önerilir. Eski IF_APJ_DT_EXEC_OBJECT + IF_APJ_RT_EXEC_OBJECT çifti hâlâ desteklenir, ama SAP belgesi onu yeni geliştirmede kullanmamayı söyler.
  2. Katalog girişi (Job Catalog Entry): Sınıfı iş çerçevesine tanıtır; seçim ekranındaki parametreleri, grupları ve bölümleri tanımlar. ADT'de Other ABAP Repository Object → Application Jobs → Application Job Catalog Entry ile oluşturulur.
  3. Şablon (Job Template): Katalog girişine bağlıdır ve parametrelerin varsayılan değerlerini taşır. Klasik dünyadaki varyantın karşılığıdır.
  4. Yetki: ABAP Cloud'da şablonun Fiori'deki "Application Jobs" uygulamasından planlanabilmesi için ADT'de ve yönetici launchpad'inde ek yetki adımları gerekir.

BTP ABAP ortamında iş sınıfının taşınabilmesi için müşteriye ait bir yazılım bileşeninde (ZLOCAL dışında) olması gerekir. On-premise S/4HANA'da da application job kullanılabilir; IF_APJ_RT_RUN'ın sisteminizin sürümünde bulunup bulunmadığını kontrol edin, yoksa eski arayüz çiftiyle aynı yapıyı kurarsınız.

İş Sınıfı ve Parametreler

IF_APJ_RT_RUN ile seçim ekranı ayrı bir metotta tanımlanmaz: sınıfın public öznitelikleri parametre olur. Çerçeve, EXECUTE'u çağırmadan önce bu öznitelikleri seçim ekranında girilen değerlerle doldurur. Örnek: onaylı masraf formlarını muhasebeye aktaran bir iş.

CLASS zcl_exp_post_job DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_apj_rt_run.

    TYPES ty_company_code_range TYPE RANGE OF zexp_report-company_code.

    "! <p class="shorttext synchronized" lang="tr">Şirket kodu</p>
    DATA company_codes TYPE ty_company_code_range.
    "! <p class="shorttext synchronized" lang="tr">Test modu</p>
    DATA test_mode TYPE abap_boolean VALUE abap_true.

  PRIVATE SECTION.
    METHODS post_report
      IMPORTING report_uuid TYPE sysuuid_x16.

ENDCLASS.

Belgede tanımlanan kurallar:

  • Öznitelik public olmalı; sabitler (CONSTANTS) ve READ-ONLY öznitelikler parametre olamaz. Ad en çok 38 karakterdir.
  • Tek değerli alan için öznitelik elementer tipte olmalıdır. STRING kullanılabilir, ama çerçeve en çok 255 karakter taşır; daha uzun değer kesilir.
  • Birden çok değer veya aralık için öznitelik bir ranges tablosu olmalıdır (TYPE RANGE OF).
  • Parametre başlığı, özniteliğin ABAP Doc açıklamasından alınır (yukarıdaki "! satırları).
  • Varsayılan değer üç yoldan verilir: özniteliğin tanımında (VALUE abap_true), constructor'da veya IF_APJ_DT_DEFAULTS arayüzünün FILL_ATTRIBUTE_DEFAULTS metodunda.
  • Tarih parametresinde şablona @STARTDAYPLUSDAY@:03 gibi dinamik bir değer yazılabilir.

test_mode'un varsayılanının abap_true olması bilinçlidir: yeni bir şablon yanlışlıkla ilk kez çalıştırıldığında hiçbir şey değiştirmez, yalnız günlüğe ne yapacağını yazar.

Hata ve Günlük

EXECUTE'un imzasında CX_APJ_RT_CONTENT istisnası vardır. SAP belgesine göre bu istisnayı bir mesajla fırlattığınızda çerçeve onu yakalar, mesajı ve kaynak konumunu içeren bir günlük oluşturur ve işin durumu Failed olur. Başka bir istisna EXECUTE içinde yakalanmazsa çalışma zamanı hatası (kısa döküm) oluşur. Bu yüzden beklenmeyen hataları da yakalayıp CX_APJ_RT_CONTENT'e çevirmek, işi izleyen kişiye anlamlı bir mesaj bırakır.

METHOD if_apj_rt_run~execute.

  TRY.
      DATA(log) = cl_bali_log=>create_with_header(
                    header = cl_bali_header_setter=>create( object    = 'ZEXP'
                                                            subobject = 'POST' ) ).

      SELECT ReportUUID, ReportID
        FROM zi_expensereport
        WHERE CompanyCode IN @company_codes
          AND Status = 'A'
        INTO TABLE @DATA(reports).

      LOOP AT reports INTO DATA(report).
        IF test_mode = abap_false.
          post_report( report-ReportUUID ).
        ENDIF.
        log->add_item( item = cl_bali_free_text_setter=>create(
                         severity = if_bali_constants=>c_severity_status
                         text     = COND #( WHEN test_mode = abap_true
                                            THEN |Test: { report-ReportID } aktarılacak|
                                            ELSE |{ report-ReportID } aktarıldı| ) ) ).
      ENDLOOP.

      cl_bali_log_db=>get_instance( )->save_log( log                        = log
                                                 assign_to_current_appl_job = abap_true ).

    CATCH cx_bali_runtime INTO DATA(log_error).
      RAISE EXCEPTION TYPE cx_apj_rt_content
        MESSAGE ID 'ZEXP' NUMBER '001' WITH log_error->get_text( ).
  ENDTRY.

ENDMETHOD.

assign_to_current_appl_job = abap_true günlüğü işe bağlar; günlük, Application Jobs uygulamasında işin ayrıntısında görünür. Günlüğün iş geri alınsa bile kalması gerekiyorsa save_log_2nd_db_connection metodu ayrı bir veritabanı bağlantısıyla kaydeder ve hemen commit eder.

İki not daha:

  • İş, kendisini çalıştıran kullanıcının yetkisiyle okur. Örnekteki zi_expensereport bir DCL rolü taşıyorsa sonuç bu kullanıcıya göre süzülür. Bütün şirket kodlarını işlemesi gereken teknik bir iş için bu durumu bilerek yönetin; ayrıntı için CDS yetkilendirme yazısına bakabilirsiniz.
  • post_report veriyi doğrudan tabloya yazmamalı. Formun durumu bir RAP iş nesnesiyle yönetiliyorsa iş de EML ile (MODIFY ENTITIES ve COMMIT ENTITIES) değiştirmelidir; böylece ekrandaki doğrulamalar, belirlemeler ve kilitler arka plan işinde de geçerli olur.

İşi Koddan Planlamak

Bir işi kullanıcının değil kodun başlatması gerekiyorsa serbest bırakılmış CL_APJ_RT_API sınıfı kullanılır. SCHEDULE_JOB metodu şablon adını, başlangıç bilgisini, periyodikliği ve parametre değerlerini alır; GET_JOB_STATUS, FIND_JOBS_WITH_JCE ve CANCEL_JOB gibi metotlarla iş izlenir ve iptal edilir.

TRY.
    GET TIME STAMP FIELD DATA(now).

    cl_apj_rt_api=>schedule_job(
      EXPORTING
        iv_job_template_name   = 'ZEXP_POST_TEMPLATE'
        iv_job_text            = 'Masraf aktarımı'
        is_start_info          = VALUE #( timestamp = now )
        is_scheduling_info     = VALUE #( test_mode = abap_false
                                          timezone  = 'UTC' )
        it_job_parameter_value = VALUE #(
          ( name    = 'TEST_MODE'
            t_value = VALUE #( ( sign = 'I' option = 'EQ' low = abap_false ) ) ) )
      IMPORTING
        ev_jobname             = DATA(job_name)
        ev_jobcount            = DATA(job_count) ).

  CATCH cx_apj_rt INTO DATA(schedule_error).
    " schedule_error->get_longtext( ) ile mesajı kullanıcıya veya günlüğe yazın
ENDTRY.

Parametre tablosu verilmezse şablondaki değerler kullanılır; verilirse yalnız içindeki parametreler şablonu geçersiz kılar. Periyodik bir iş için is_scheduling_info'da periyot (periodic_granularity, periodic_value), is_end_info'da bitiş koşulu verilir. Metodun zorunlu ve isteğe bağlı parametreleri sürüme göre değişebildiği için sınıf belgesini kontrol edin.

RAP içinden planlarken: SAP belgesine göre start_immediately bir RAP iş nesnesinin içinden kullanılamaz, çünkü alttaki API örtük bir COMMIT WORK yapar. Hemen başlaması gereken işi bir zaman damgasıyla planlayın (yukarıdaki gibi); sistem yüküne göre kısa bir gecikmeyle başlar.

bgPF: Kayıttan Sonra Arka Planda

Background Processing Framework (bgPF), bir uygulamanın metotlarını arka planda, asenkron ve güvenilir biçimde çalıştırır. bgRFC üzerine kuruludur, transactional ve sıralı (queued) süreçleri destekler ve ABAP Cloud'un standart parçasıdır. On-premise tarafta S/4HANA 2023 ile gelir ve kısa bir yapılandırmadan sonra kullanılabilir.

En önemli özelliği zamanlamasıdır: süreç save_for_execution ile kaydedilir, ama ancak başlatan işlem COMMIT WORK ile tamamlandığında çalışır. İşlem geri alınırsa süreç hiç başlamaz. Yani "form onaylandıysa bildirim gönder" kuralı, onay kaydedilmeden bildirimin gitmesi riskini kendiliğinden ortadan kaldırır.

İki tür operasyon vardır:

Controlled (transactional kontrollü): IF_BGMC_OP_SINGLE

RAP uygulamaları için önerilen türdür. EXECUTE metodu modify aşamasında başlar: okuma ve hesaplama serbesttir, veritabanı değişikliği yasaktır. cl_abap_tx=>save( ) ile save aşamasına geçildikten sonra kalıcı değişiklik yapılır. EXECUTE içinde COMMIT WORK yazılmaz; bunu çerçeve yapar. Süreç set_operation ile verilir.

Uncontrolled: IF_BGMC_OP_SINGLE_TX_UNCONTR

Transactional kontrol gerekmeyen, RAP dışındaki durumlar içindir; ek kısıtlama yoktur. Süreç set_operation_tx_uncontrolled ile verilir. Esnekliğin bedeli, işlem bütünlüğünün tamamen size kalmasıdır.

Controlled bir operasyon, masraf formu onaylandığında bildirim kaydı oluşturan bir adım olarak şöyle yazılabilir:

CLASS zcl_exp_notify_op DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_bgmc_op_single.
    METHODS constructor
      IMPORTING report_uuid TYPE sysuuid_x16.

  PRIVATE SECTION.
    DATA report_uuid TYPE sysuuid_x16.

ENDCLASS.

CLASS zcl_exp_notify_op IMPLEMENTATION.

  METHOD constructor.
    me->report_uuid = report_uuid.
  ENDMETHOD.

  METHOD if_bgmc_op_single~execute.
    " modify aşaması: okuma ve hesaplama serbest, veritabanı değişikliği yasak
    SELECT SINGLE ReportID, CreatedBy
      FROM zi_expensereport
      WHERE ReportUUID = @report_uuid
      INTO @DATA(report).

    IF sy-subrc <> 0.
      RETURN.
    ENDIF.

    " save aşamasına geçiş
    cl_abap_tx=>save( ).

    " save aşaması: kalıcı değişiklik
    INSERT zexp_notif FROM @( VALUE #( report_uuid = report_uuid
                                       recipient   = report-CreatedBy
                                       created_at  = utclong_current( ) ) ).
  ENDMETHOD.

ENDCLASS.

Operasyon nesnesi yalnız bir anahtar taşıyor. Constructor'da verilen öznitelik arka plan çalışmasında da kullanılabilir; ama formun güncel hâli EXECUTE içinde yeniden okunuyor. Arka plan adımı, kullanıcının işlemiyle aynı anda değil, biraz sonra çalışır. O arada değişebilecek veriyi nesnenin içinde taşımamak bu yüzden daha güvenlidir.

bgPF'yi RAP'ten Başlatmak

RAP dışında süreç kaydedildikten sonra açık bir COMMIT WORK gerekir. RAP içinde ise commit'i çerçeve yapar; süreç kaydetme sırasında oluşturulur. Managed bir iş nesnesinde bunun yeri, with additional save ile açılan saver sınıfının save_modified metodudur:

METHOD save_modified.

  LOOP AT update-expensereport INTO DATA(report)
       WHERE %control-Status = if_abap_behv=>mk-on
         AND Status = 'A'.
    TRY.
        DATA(process) = cl_bgmc_process_factory=>get_default( )->create( ).
        process->set_name( |Masraf bildirimi { report-ReportID }| ).
        process->set_operation( NEW zcl_exp_notify_op( report-ReportUUID ) ).
        process->save_for_execution( ).
      CATCH cx_bgmc INTO DATA(bgmc_error).
        " süreç kaydedilemedi: uygulama günlüğüne yazın
    ENDTRY.
  ENDLOOP.

ENDMETHOD.

Onay geri alınırsa (bir doğrulama hatası, bir kilit çakışması) RAP işlemi commit etmez ve bildirim süreci hiç başlamaz. Kullanıcı ise onay düğmesine bastıktan sonra bildirim işinin bitmesini beklemez. RAP'ın kaydetme sırası ve saver sınıfı için SAP RAP rehberine bakabilirsiniz.

bgPF'yi İzlemek

save_for_execution bir monitör nesnesi döndürür. Bu nesnenin get_state metodu sürecin durumunu (yeni, başarılı, hatalı gibi) verir. Monitör to_string ile metne çevrilip saklanabilir ve sonra cl_bgmc_process_factory=>create_monitor_from_string ile geri yüklenebilir. Bu, kullanıcıya "bildirim gönderildi mi?" sorusunun cevabını göstermek için kendi tablonuzda süreç izini tutmanın kolay bir yoludur.

bgPF bgRFC üzerine kurulu olduğu için kuyruklar bgRFC izleme araçlarında da görünür. İzleme ayrıntıları bulut ve on-premise sürümleri arasında farklı olabilir; kendi sisteminizdeki araçları canlıya geçmeden önce deneyin.

Tasarım Önerileri

  • Tekrar çalıştırılabilir yazın. Bir iş yarıda kesilip yeniden başlatılabilir. "Aktarılmamış onaylı formlar" gibi durum tabanlı bir seçim, "dünün formları" gibi zaman tabanlı bir seçimden daha güvenlidir: ikinci çalıştırma, birincinin yaptığını tekrarlamaz.
  • Test modu ve günlük. Her toplu işin bir test modu ve okunabilir bir günlüğü olsun. Günlüğü okuyacak kişi çoğu zaman geliştirici değil, kilit kullanıcıdır.
  • bgPF'ye ağır iş yüklemeyin. bgPF bir işlemin devamı içindir; binlerce kaydı işleyen bir toplu iş, izlenebilir bir application job olarak daha doğru yerdedir.
  • İş mantığını tek yerde tutun. Ekrandan ve arka plandan aynı değişiklik yapılıyorsa ikisi de aynı RAP iş nesnesini kullansın; arka plan işi için ikinci bir doğrulama kopyası yazmayın.
  • Performansı ölçün. Uzun süren bir iş için önce sürenin nereye gittiğini bulun; ABAP performans analizi yazısındaki araçlar arka plan işleri için de geçerlidir.

Sık Yapılan Hatalar

Her şeyi application job yapmak

"Onaydan sonra bildirim gönder" için her beş dakikada bir çalışan bir iş kurmak, hem gecikme hem de gereksiz yük demektir. Bir işlemin devamı olan adım bgPF'ye aittir.

Controlled operasyonda modify aşamasında yazmak

cl_abap_tx=>save( ) çağrılmadan yapılan veritabanı değişikliği çalışma zamanı hatasına yol açar. Önce oku ve hesapla, sonra aşamayı değiştir, sonra yaz.

CX_APJ_RT_CONTENT dışındaki istisnaları kaçırmak

Yakalanmayan bir istisna, anlamlı bir mesaj yerine kısa döküm bırakır. Beklenmeyen hataları yakalayıp CX_APJ_RT_CONTENT'e çevirin.

RAP içinden start_immediately ile iş planlamak

API örtük commit yapar ve RAP işlem kurallarını bozar. Zaman damgasıyla planlayın.

Arka plan işinde tabloya doğrudan yazmak

Ekrandaki doğrulamalar arka planda atlanır ve aynı nesne iki farklı kuralla değişir. RAP iş nesnesi varsa EML kullanın.

Yetki bağlamını unutmak

İş, çalıştıran kullanıcının yetkisiyle okur. DCL'li bir görünüm, test kullanıcısında bütün veriyi, canlıdaki iş kullanıcısında yalnız bir kısmını getirebilir.

Sonuç

ABAP Cloud'da arka plan işi tek bir araç değil, iki ayrı sorunun iki ayrı cevabıdır. Takvime bağlı, parametreli ve izlenmesi gereken işler application job'dur: sınıf, katalog girişi, şablon ve günlük. Bir kullanıcı işleminin, o işlem başarılı olursa arka planda devam etmesi gereken adımı ise bgPF'dir: kayıtla birlikte doğar, geri almayla birlikte ölür. Bu ayrım doğru yapıldığında hem kullanıcı beklemez hem de "bildirim gitti ama kayıt yok" türünden tutarsızlıklar ortadan kalkar.

Mevcut SM36 işlerinizi ve asenkron fonksiyon çağrılarınızı ABAP Cloud'a taşımak için sunduğum kapsamı süreç otomasyonu hizmet sayfasında bulabilirsiniz.

Klasik arka plan işlerinizi Application Jobs ve bgPF'ye taşımak, RAP uygulamanıza asenkron adımlar eklemek veya mevcut işlerin hata yönetimini iyileştirmek için destek alın.

Ön Görüşme Talep Et
← Blog'a Dön

İletişim

Projeleriniz için iletişime geçin.