When an entity is declared with draft; in its Behavior Definition (BDEF), the SAP RAP engine coordinates three storage tiers:
| Storage Tier | Physical Persistence | Data Lifecycle & Scope | Lock Mechanism |
|---|---|---|---|
| Active Persistence | Standard ERP Table (e.g., ZSD_ORDER_A) |
Authoritative, fully validated, committed transactional records. | Optimistic ETag check on edit. |
| Draft Persistence | Draft Staging Table (e.g., ZSD_ORDER_D) |
Temporary working state; allows incomplete, unvalidated inputs. | Exclusive enqueue lock held by active editing user. |
| Transactional Buffer | Application Server Memory (Internal Tables) | In-flight modifications during the current interaction phase. | Process memory boundaries. |
The RAP framework provides built-in draft actions that govern transition between active and draft states:
Edit: Reads the active record, copies it into the draft table, sets draftinprocessbyuser, and takes an exclusive enqueue lock.Activate: Executes standard validations and determinations in the CHECK_BEFORE_SAVE phase. If valid, writes draft state to active persistence and purges the draft row.Discard: Drops the draft row completely, reverts any pending changes, and immediately releases the exclusive enqueue lock.Resume: Re-associates a user's browser session with their existing draft after session timeout.Prepare: Triggers validations on draft data before explicit activation to surface UI field errors.To prevent the "Lost Update" problem where User B overwrites User A's uncommitted changes, RAP mandates two levels of ETag definitions:
managed implementation in class zbp_r_order_root unique;
strict ( 2 );
with draft;
define behavior for ZR_ORDER_ROOT alias Order
persistent table zsd_order_a
draft table zsd_order_d
lock master total etag LastChangedAt // Checks concurrent edits on active record
etag master LocalLastChangedAt // Checks concurrent edits on draft buffer
{
draft action Edit;
draft action Activate optimized;
draft action Discard;
draft action Resume;
draft determine action Prepare;
field ( readonly, numbering : managed ) OrderUUID;
field ( readonly ) OrderID, CreatedAt, CreatedBy, LastChangedAt;
create;
update;
delete;
}
In high-volume systems, users frequently abandon browser sessions or close laptop lids without clicking "Save" or "Cancel". This creates two major problems:
Z*_D tables, slowing down indexing and CDS joins.DELETE FROM zsd_order_d! Directly deleting database rows bypasses the enqueue server, leaving phantom lock entries in transaction SM12. Always trigger EML EXECUTE Discard.
The following is the contract-compliant method for discarding stale draft records programmatically:
" =====================================================================
" Method: Purge Stale Drafts via EML
" Language Version: ABAP Cloud (Language Version 5)
" =====================================================================
METHOD purge_expired_drafts.
DATA(lv_cutoff) = utclong_add( val = utclong_current( ) hour = -72 ).
" 1. Query expired drafts via administrative metadata
SELECT OrderUUID
FROM zsd_order_d
WHERE draftlastchangedatetime < @lv_cutoff
INTO TABLE @DATA(lt_expired).
CHECK lt_expired IS NOT INITIAL.
" 2. Construct Discard EML payload
DATA: lt_discard TYPE TABLE FOR ACTION IMPORT zr_order_root~Discard.
lt_discard = VALUE #(
FOR ls IN lt_expired (
%tky-%is_draft = if_abap_behv=>mk-on
%tky-OrderUUID = ls-OrderUUID
)
).
" 3. Execute framework discard action
MODIFY ENTITIES OF zr_order_root
ENTITY Order
EXECUTE Discard FROM lt_discard
FAILED DATA(lt_failed)
REPORTED DATA(lt_reported).
" 4. Release locks
COMMIT ENTITIES.
ENDMETHOD.
Explore free client-side interactive utilities to accelerate your S/4HANA migration: