Skip to Content
Technical Articles

Etag In Odata

This blog post will give the basic overview for beginners on the Etag topic in Odata.

Introduction

E tag is used for Data Concurrency to avoid over writing of same record at the same time by different users similar to Lock objects.

Scenario for Etag

User  1  and user 2 will get the same record from backend  , user 1 will update the data and save the record in database , user 2 without knowing data has been already updated to the record which he supposed to update he  will update the same record and saves the data , at this time data saved by user1 will be overwritten by data of user 2 , this is  not supposed to happen , this leads to data inconsistency  to avoid this  we will go for ETag (Entity tag) .

In etag  we will have field which will uniquely  identify each updating of the record whenever its updated , this field values can be generated using hash algorithm  or a timestamp filed can be used to generate the etag value , which will prevent the unnecessary or concurrent updation of same record by different users at same time  in this blog post we will see how can achieve this by using hash algorithm .

Procedure:

Created a custom table with spfli fields along with Etag Field  DB table ZSPFLI_ETAG.

Custom Table ZSPFLI_ETAG with Etag

Custom%20Table%20ZSPFLI_ETAG%20with%20Etag

Image source (sunila.k abap consultent)

Here the field etag has the standard data type hash160 which stores the etag value .

 

At first There will Be no Etag values  in table For newly created records.

 Create a odata project and import ->DDIC Structure in form se11.

Double click on Entity type and mention etag field under Etag column as shown below.

Generate Runtime artifacts.

These Methods will be generated as shown above.

In Data provider extension add the method CALC_HASH as shown Below.

This method will have two parameters

1 .PI_DATA (impoting type ANY) for importing data from any stucture

2.PE_HASH_160(Returning type Hash160) for returning the calculated hash value for Etag.

The Function Module  ‘CALCULATE_HASH_FROM_RAW’ can be used to calculate hash vaules as shown below.

After this we will redefine the method ZFLIGHTETAGSET_GET_ENTITY  to get single record form db table(Zsflight_etag) and in runtime we will calculate the hash value for that record by calling CALC_HASH method and return it to ER_ENTITY.

Code In ZFLIGHTETAGSET_GET_ENTITY

method ZFLIGHTETAGSET_GET_ENTITY.

data : ls_spfli type zspfli_etag  ,
        lt_spfli type table of zspfli_etag ,
        ls_key_tab1 type /IWBEP/S_MGW_NAME_VALUE_PAIR ,
        ls_key_tab2 type /IWBEP/S_MGW_NAME_VALUE_PAIR.

read table it_key_tab into LS_KEY_TAB1 index 1.
read table  it_key_tab into LS_KEY_TAB2 index 2 .

select single  *  from zspfli_etag INTO ls_spfli where CARRID = ls_key_tab1-VALUE and CONNID = ls_key_tab2-VALUE .

if sy-subrc <> 0.

raise EXCEPTION type /IWBEP/CX_MGW_BUSI_EXCEPTION
EXPORTING
textid = /IWBEP/CX_MGW_BUSI_EXCEPTION=>BUSINESS_ERROR
message = 'Data of Flight schedule is not Available'.

else.

ls_spfli-ETAG = me->CALC_HASH( ls_spfli ).

er_entity = LS_SPFLI .

endif.

endmethod.

Similarly we will redefine the method ZFLIGHTETAGSET_GET_ENTITYSET to get multiple record from Db table(Zsflight_etag)  and in runtime we will calculate hash value for those records using CALC_HASH method and return it to ET_ENTITYSET.

Code for ZFLIGHTETAGSET_GET_ENTITYSET

 method ZFLIGHTETAGSET_GET_ENTITYSET.

 data :lt_spfli type table of zspfli_etag ,
       ls_spfli type zspfli_etag  ,

       TS_ZFLIGHTETAG like line of et_entityset .


 SELECT * from zspfli_etag into table lt_spfli .

if sy-subrc = 0 and lt_spfli is not INITIAL.

  loop at lt_spfli into ls_spfli .

ls_spfli-ETAG = me->CALC_HASH( ls_spfli ).

 MOVE-CORRESPONDING ls_spfli to TS_ZFLIGHTETAG.

append TS_ZFLIGHTETAG to ET_ENTITYSET.

clear TS_ZFLIGHTETAG.

endloop .
else.

raise EXCEPTION type /IWBEP/CX_MGW_BUSI_EXCEPTION
EXPORTING
textid = /IWBEP/CX_MGW_BUSI_EXCEPTION=>BUSINESS_ERROR
message = 'Data of Flight schedule is not Available'.



endif.

  endmethod.

After Updating the Retrived Record we need to update the data to the backend db table (Zsflight_Etag) so redefine the update entity method ZFLIGHTETAGSET_UPDATE_ENTITY in this method I have written code for updating single record.

Code for ZFLIGHTETAGSET_UPDATE_ENTITY

method ZFLIGHTETAGSET_UPDATE_ENTITY.

data: lv_data TYPE ZCL_ZFLIG_SHECDULE_ETA_MPC=>TS_ZFLIGHTETAG,
      ls_key_tab like line of it_key_tab.

io_data_provider->READ_ENTRY_DATA(
  importing
    ES_DATA                      = lv_data
).
update zspfli_etag from lv_data.

if sy-subrc <> 0.

raise EXCEPTION type /IWBEP/CX_MGW_BUSI_EXCEPTION
EXPORTING
textid = /IWBEP/CX_MGW_BUSI_EXCEPTION=>BUSINESS_ERROR
message = 'Update Faild'.

endif.
endmethod.

 

Testing :

After Activating all The Redefined Methods Now its item to test The ETAG functionality of the Generated service.

Our entityset Is having two key Fields . (CARRID ,CONNID).

Scenario 1:

In This case hanauser10    and hanauser12 will get the same record from the  Db edit the data and they will update the data to the db .

First hanauser12 will get the data from db(Zsflight_etag)

Similarly  Hanauser10 at the same time will get the data from the db(Zsflight_etag)

We can notice here that both the users hanauser12 and hanauser10  Etag  value “’DECCF262A55DE81712793ACEB402F561C61D3627’” generated is same ,since both the users are in same client .

Now Hanauser12 will click on use as request button to edit the data user will change filed :Cityfrom from Chicago to Newyork.

Hanauser12 will Now add etag value in Pop Up By clicking on ADD Header Button as Shown

Fill Header Name Filed  “If-Match’’.

Header Value Field  W/”DECCF262A55DE81712793ACEB402F561C61D3627”’

And Upadtes The data by changing The Http PUT Method .

The data will Be Updated In backend Table with Respose 204.

Data will Be updated To the backend Table as shown below with Etag value .

Now hanauser10 will try to update the data with the same etag value W/”DECCF262A55DE81712793ACEB402F561C61D3627”’ by changing the Filed City from Nework to Denver .

And will Get the error message saying PRECONDITION FAILED with status code 412 .

This is because there is already a record in the Db(Zspflig_etag) which is updated with the same etag value that’s why system raises this error thus achiving the main purpose of Etag avoiding Data Inconsistancy.

Procedure followed by Hanauser10  to update data for same record:

If  Hanauser10 wants to update the data then user has to get the New etag value by performing get operation This time user will get updted data which Hanauser12 has updated before so then Hanauser10 will update the record by New etag value .

Before user 10 updates the data to DB.

After user 10 updated the record with  new etag value  W/”’D30ABE6B162E68100B85545A27BC03868426EFCF’” in db.

 

Scenario2:

In this scenario hanauser12 will  has already updated the data once with the Etag value W/”’62D3277034FC4C90AD026137FED2B238390A45A5’” The Field: CityForm  is updated  to Chicago.

 DB is updated As shown below.

Hanauser12  Now wants to change the Cityto Field to from SAN Francisco to Newyork  so hana Hanauser12  will try to uptade with same  etag value Then The system Throws error 412 since the etag value is already updated .

Hanauser12 Just wants to change the Field: Cityto value to SAN Francisco to Newyork  without changing the etag value user don’t  want to change the existing etag value so  user will make use of

IF-None-Match content-type  to achive this .

If-None-Match” which will check the Etag present first and proceed if there is mismatch

Last updated value in db by using if none match keyword by Hanauser12 you can notice the ETAg value  remain unchanged But  CityTo Field value is changed to SaNFrancisco to Newyork.

Conclusion

Using this Etag concept we can easily identify the particular record uniquely with Etag value when the particular record is updated  or changed , and avoid overwriting of data .

References

https://sapyard.com/tag/etags/

 

1 Comment
You must be Logged on to comment or reply to a post.
  • Appreciate the effort, Sunila, but I’m sorry to say this blog does not seem to add anything to the original blog referenced at the end.

    It seems that you’ve just followed the process from that blog and then pasted screenshots here. It’s cool but it’s been a few years after the original blog, so maybe you could’ve instead explored how this is done in RAP model, for example? Or maybe shared some additional information you’ve learned in the process?

    Also it would be great if you could write in shorter sentences, use spell checker and use proper capitalization. I’m honestly curious what prompted capitalization in this sentence, for example: “And Upadtes The data by changing The Http PUT Method”. It should look something like this: “And [it?] updates the data by using HTTP PUT method”. English is not the first language for me and I’d never criticize anyone for minor errors (which I definitely make as well). But this type of sloppy writing is simply inexcusable and unprofessional. There is software and online tools that can help with spelling and grammar check.