In classic SAP GUI transactions, when User A entered transaction VA02, the system acquired an exclusive SAP Enqueue lock on the sales order table. Any other user attempting to open the same order received an immediate lock error: "Document is locked by User A".
In modern SAP Fiori and web-based applications, HTTP connections are stateless. Holding database connections or permanent exclusive locks while a user has a browser tab open is architecturally infeasible. However, without concurrency control, the Lost Update Problem emerges: User A and User B open the same record simultaneously; User B saves first, and User A unwittingly overwrites User B's edits.
SAP RAP resolves this using an innovative two-layer architecture combining Optimistic Concurrency (ETags) and Pessimistic Draft Locking (Enqueue Integration):
| Concurrency Layer | Mechanism | When Evaluated | Clean Core Responsibility |
|---|---|---|---|
| 1. Master ETag (Local) | HTTP If-Match header with timestamp hash |
On every single CUD operation (Active & Draft) | Guarantees atomic row consistency between client and server |
| 2. Total ETag (Root) | Root entity timestamp (lastChangedAt) |
During Draft Activate action |
Ensures active entity was not modified out-of-band by another user/job |
| 3. Draft Enqueue Lock | SAP Enqueue Server exclusive lock | When user enters Edit mode on Draft | Prevents two users from simultaneously drafting the same active record |
Developers frequently confuse etag master with total etag:
etag master): Annotated in CDS with @Semantics.systemDateTime.localInstanceLastChangedAt: true. Updated whenever that specific instance (e.g. Sales Order Item 20) is modified.total etag): Annotated on Root with @Semantics.systemDateTime.lastChangedAt: true. Updated only when the active entity commit occurs. Used exclusively by the RAP Draft engine during Activation.managed implementation in class zbp_r_salesorder unique;
strict ( 2 );
with draft;
define behavior for ZR_SalesOrder alias Order
persistent table zt_order_hdr
draft table zt_order_hdr_d
lock master total etag LastChangedAt
authorization master ( global, instance )
etag master LocalLastChangedAt
{
create;
update;
delete;
association _Items { create; with draft; }
draft action Edit;
draft action Activate optimized;
draft action Discard;
draft action Resume;
draft determine action Prepare;
}
define behavior for ZR_SalesOrderItem alias OrderItem
persistent table zt_order_itm
draft table zt_order_itm_d
lock dependent by _Order
authorization dependent by _Order
etag master LocalLastChangedAt
{
update;
delete;
association _Order { with draft; }
}
When an OData V4 client receives 412 Precondition Failed, it indicates the client supplied an outdated ETag in the If-Match header. In SAP Fiori Elements apps:
@Core.OptimisticConcurrency).ETag: W/"..." response headers.Generate validated BDEF definitions, Total ETag configurations, and draft locking hierarchies with our interactive tool.
Launch Concurrency Architect âš¡ Get Architecture Suite (80% Off)