SAP CRM Fiori采用了這種機制。
看一個具體的例子來了解。假設我用使用者名Jerry選中了這個ID為3456的Opportunity,點選Edit按鈕之後:
會觸發一個讀操作發到背景:
背景響應這個讀請求,并且在響應的頭部字段ETAG裡寫入了對應的值。
這個26AE結尾的ETAG的值可以由應用程式采取不同的邏輯計算,可以直接采用請求節點對應的最後修改時間戳(Last Changed Timestamp), 例如下面這段ABAP代碼:
也可以基于資料的完整内容計算一個HASH值出來作為ETAG傳回給Fiori UI:
現在我用另一個使用者,對同一個Opportunity做了修改,成功儲存。然後再回到使用者Jerry的這個編輯視窗,此時Jerry根本不知道該Opportunity已經被另一個使用者修改了。Jerry修改了Opportunity的Name字段,點選儲存按鈕。
收到這個提示資訊。
從Chrome Development Tool裡能觀察到,當Jerry點選了儲存按鈕後,發送到背景的請求的頭部包含了一個If-Match字段,這個字段的值就是Jerry第一次點選編輯按鈕時,背景傳回給Jerry的26AE結尾的ETAG字段。
背後發生了什麼事請呢?在架構的方法CHECK_BEFORE_MODIFICATION裡,架構會把Fiori UI請求傳進來的ETAG和目前最新的ETAG做比較:
CHECK_BEFORE_MODIFICATION又會調用CHECK_ETAG_MATCH方法。如果check失敗,目前的儲存操作将不會執行。
這種方式用于S/4HANA的Fiori應用,比如Material application。這種Fiori應用,消費的OData service是基于CDS view 加上BOPF實作的。
打開一個Material,點選Edit:
此時到ABAP背景使用事務碼SM12能觀察到Material對應的資料庫表被鎖住了:
這是怎麼實作的呢?
在S/4HANA背景使用事務碼BOBX打開BO模型I_PRODUCTWD. 展開模型,輕按兩下EDIT,能看到這個Edit實作的類為CL_I_DR_PRODUCTWD.
輕按兩下這個class,它的方法LOCK_ACTIVE_DOCUMENT就是響應Fiori UI上編輯按鈕點選的處理函數。
我們在這個方法裡設定斷點,然後在UI上點選編輯按鈕,斷點觸發。從調用棧即可清除觀察到編輯按鈕點選之後,程式執行流是如何從BOPF架構投遞到Material應用的枷鎖代碼。這個加鎖邏輯調用的是傳統的ABAP Enqueue function module。