Architecture Guide #22 • ABAP Cloud Event-Driven Architecture

SAP RAP Transactional Outbox Pattern & Guaranteed Event Delivery

A production engineering guide on eliminating the dual-write hazard between SAP HANA and SAP Event Mesh using the Transactional Outbox Pattern, RAP save sequences, and Application Jobs.

Interactive Generator: Automatically generate the complete Outbox table DDL, RAP behavior pool save_modified enqueue logic, and Application Job dispatcher with our In-Browser RAP Outbox Generator.

1. The Dual-Write Hazard in Event-Driven S/4HANA

When developing modern event-driven integrations in SAP S/4HANA, developers frequently attempt to publish CloudEvents to SAP Event Mesh directly inside RAP determinations or validations via HTTP/REST destinations.

The Dual-Write Problem: If the HTTP request to SAP Event Mesh succeeds, but a subsequent validation in RAP fails (triggering a rollback of the SAP HANA transaction), the external world receives a notification for a business transaction that was never committed in the database!

Conversely, if the database transaction commits but the network call to Event Mesh times out, the event is permanently lost. Distributed two-phase commit (XA transactions) is unsupported across cloud microservices.

2. The Transactional Outbox Solution

The Transactional Outbox Pattern solves this dilemma by storing the event in an Outbox database table inside the same local database transaction as the business object changes:

  1. Atomic Save: In RAP save_modified, the business document and the corresponding CloudEvent payload are inserted into the database together. If the commit succeeds, both exist; if it rolls back, neither exists.
  2. Asynchronous Dispatcher: A background daemon (SAP Application Job via cl_apj_rt_api) polls the Outbox table for status = 'P' (Pending).
  3. Guaranteed Delivery: The dispatcher posts the CloudEvent to SAP Event Mesh. On HTTP 200/204 response, it marks the event status = 'S' (Sent).
  4. Exponential Backoff & DLQ: If the remote broker is unavailable, retries are attempted up to 3 times before routing to a Dead-Letter Queue (DLQ).

3. CloudEvents 1.0 Specification Compliance

Every event queued in the Outbox should adhere to the CNCF CloudEvents standard:

lo_req->set_header_field( i_name = 'Content-Type' i_value = 'application/cloudevents+json' ).
lo_req->set_header_field( i_name = 'ce-id'          i_value = -event_id ).
lo_req->set_header_field( i_name = 'ce-specversion' i_value = '1.0' ).
lo_req->set_header_field( i_name = 'ce-type'        i_value = -event_type ).
lo_req->set_header_field( i_name = 'ce-source'      i_value = '/sap/s4hana/clean-core' ).

4. Idempotency on Consumer Side

Because the Outbox pattern guarantees at-least-once delivery, network glitches during acknowledgment may cause the dispatcher to resend an event. Consumers on SAP BTP (CAP / Node.js / Java) must implement idempotency checks using the unique ce-id attribute.

Master Enterprise RAP & Clean Core Architecture

Get the complete 400+ page guide with end-to-end architectures, testing patterns, and migration blueprints:

Unlock Complete Enterprise Suite (80% Off • €9.80) → Also available in Paperback & Kindle on Amazon ($19.99)