logo

Are you need IT Support Engineer? Free Consultant

Handling Concurrent Updates in SAP CAP Java

  • By sujay
  • 26/05/2026
  • 6 Views

How It Works: ETags

Optimistic locking on the web is implemented using ETags, a standard HTTP mechanism.

When a record is retrieved, the server includes an ETag in the response. This acts as a version identifier that changes whenever the record is updated.

When sending an update, the client includes this ETag in the If-Match header, effectively stating: apply this update only if the record is still on the same version I read.

The server then compares the provided ETag with the current version:

  • Match → The record is unchanged, the update is applied, and a new ETag is generated
  • Mismatch → The record has been modified by someone else, and the request is rejected with 412 Precondition Failed

This ensures updates are applied only to the latest version of the data, preventing silent overwrites.

How SAP CAP Java Does It

SAP CAP Java handles all of this automatically. We just need to tell the framework which field to use as the ETag.

We can do that with a single annotation in our CDS model:

The managed aspect automatically maintains the modifiedAt timestamp, updating it whenever the record is changed. By annotating this field with @odata.etag, SAP CAP uses it as the entity’s version identifier (ETag).

From that point onward, concurrency control is handled automatically. For every update request, SAP CAP validates the incoming If-Match header against the current value of modifiedAt. If the values differ, the framework rejects the update with an HTTP 412 Precondition Failed response, preventing stale data from overwriting newer changes.

No additional Java code is required.

Seeing It in Action

Let us start the application and create an employee record:

Chatgpt Image May 25, 2026, 08_00_56 Pm.png

As we can see the response contains the ETag value: 2026-05-25T06:55:44.400909Z

Let us simulate Alice’s request of updating the email with the ETag we just received:

Chatgpt Image May 25, 2026, 08_04_32 Pm.png

This succeeds. The record is updated and a new ETag is generated.

Now, simulating Bob's request (who is working with the older version) using the older ETag value.

Chatgpt Image May 25, 2026, 09_00_35 Pm.png

Bob's request is rejected with 412 Precondition Failed.
Alice's change is safe.

What Happens Next: Resolving the Conflict

A 412 Precondition Failed response is not an error to suppress – it is a signal that the data has changed since it was last read.
At this point, the user can reload the latest version of the data, review the differences, and reapply their changes with full context before saving again.

Hence, Bob retrieves the latest version of the record and obtains the updated ETag value.

Whatsapp Image 2026-05-25 At 8.40.19 Pm.jpeg

Bob resubmits his update using the fresh ETag:  2026-05-25T07:07:15.691711Z

Whatsapp Image 2026-05-25 At 8.42.51 Pm.jpeg

This time it succeeds. Both changes are now in the record. Nothing was lost.

The key insight is that a 412 is not a failure – it is a safety net doing its job. The system caught a potential lost update before it happened and gave Bob the opportunity to resolve it cleanly.

Conclusion

Concurrency-related data integrity issues are particularly problematic because they occur silently. When two users update the same record, the later save succeeds and the earlier change is overwritten without any indication of a conflict.

Optimistic locking is the standard approach to preventing this class of issue, and SAP CAP Java provides built-in support. By adding a simple @odata.etag annotation, the framework can automatically detect stale updates and reject conflicting changes before any data is lost.

It is a minimal change to the data model, but one that significantly improves the consistency and reliability of enterprise applications.

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *