Maintain Data Concurrency in OData ( UI5 Ressource Locking )
Monday, 31 October 2016
More than one user has access to the same entity and hence the same data in SAP Fiori applications. So how to prevent parallel edit access for users so as to prevent the data from being overwritten in flight.
There are three ways to lock records to manage the concurrency.
In this scenario the application assumes that concurrent writes will occur and hence protects it by aggressively locking out resources. This can lead to deadlocks and also have some performance reduction as applications using the resource will have to wait in queue to apply its changes.
In this scenario the application assumes that the likelihood of a concurrent write is rare and so allows the operation to continue.
This is a combination of pessimistic and optimistic concurrency controls. This kind of solution is used for very specific scenarios.
For Data Concurrency OData recommends implementing Entity tags or ETAG’s. Since OData uses HTTP protocols and is stateless, it can use only optimistic concurrency control of data and only that is discussed in detail further in this paper.
Implementing ETags in SAP Gateway
SAP Gateway allows three ways to implement ETags.
1. A field based ETag (typically a timestamp)
When an entity is typically a subset of a database table and the database has a field that maintains a timestamp to signify a change whenever the record changes, then that field could be included in the entity and can be used as the E-Tag.
In transaction SAP Gateway Service Builder (SEGW), at the Entity Types, you select a field as your ETag property. Save and re-generate the Service.
2. A full entity based ETag (typically a timestamp)
The shortcoming of the above method is that, there are scenarios where only a few fields from a database is exposed in an entity model. But changes to the DB table in the backend can occur through various sources including background programming, manual changes through backend transactions etc. These backend changes might not have changed the Entity fields at all, but still that will be considered as a change.
In such a scenario the full entity based ETag could be implemented.
Include a Field ETAG with data element HASH160 into the entity. And use that field as the ETag property for the entity.
Once all data for the entity is fetched the hash value calculation happens.
3. Partial entity based ETag
Whatever ETag method that we implement will apply for all operations except Create. There are scenarios where the get_entityset implementation and get_entity implementation of the same Entity might not have same ETag values. This is due to that fact that there are certain information in an Entity which will be costly to fetch during a get_entityset operation. In such a scenario the partial entity based ETag could be implemented.
The implementation of partial entity based ETag is very similar to the full entity based Etag. The only change is the calculation of hash value.
Here instead of passing the complete entity, you remove the values for fields that you do not want to be part of the hash value calculation and then call the calculate hash.
Using ETags in Fiori
Classic Scenario with Etags
During the get entity if a valid etag is provided and the entity has not changed then the server responds with return code 304 (Resource not modified). If the entity has changed then the new set of data is returned with return code 200.
if you do not want to check against an existing e-tag, but get the data anyway you can use ‘*’ to get the data.
Update/Merge/Delete Entity uses the http header variable If-Match
If a valid e-tag is provided, the OData infrastructure checks for the hash value by calling the get_entity and verifies the passed e-tag value. If it is successful the update/merge/delete operation proceeds without any issues. If the e-tag does not match then the server returns status code 412 (Precondition failed.).
As a developer if you want to any how update the data from client (while using the SAP Gateway Client for testing purpose) then you can pass the If-Match value as a ‘*’, which means the client will win and will update the data irrespective.
During the Update/Merge/Delete options in case of a ETag get_entity call is made in the backend before the update call to verify the ETag value.