hazelcast EntryUpdatedListener oldValue
用了好一陣子的hazelcast EntryUpdatedListener,
突然發現到偶爾會有取不到oldValue的狀況。
這下子當需要舊值來判斷狀態變動程式碼全部完蛋,只好乖乖的檢查問題在哪裡。
慘案 EX
後來發現問題出在有些程式碼更新map的資料使用效能較好的
void com.hazelcast.core.IMap.set(String key, DeviceStatus value)
根據api doc說明
Warning:
This method breaks the contract of EntryListener.
When an entry is updated by set(),
it fires an EntryEvent with a null oldValue.
實際測試程式碼 用set的方式的確不會取到oldValue
,所以改回get就修(?)好了
,最後改code的也不是我XD
雖然是從來沒有使用過set方法,
但看code的時候完全沒發現使用的方法不同,
只聚焦在是不是有做過刪除或是set null...
突然發現到偶爾會有取不到oldValue的狀況。
這下子當需要舊值來判斷狀態變動程式碼全部完蛋,只好乖乖的檢查問題在哪裡。
慘案 EX
EntryEvent{
entryEventType=UPDATED
, member=Member[192.168.31.22]:2901
, name='Device'
, key=xxzz,
oldValue=null,
value=yyyy
, mergingValue=null
}
一開始檢查的範圍- 找到邏輯上是否有會移除資料或是將資料設為NULL的程式碼
結果當然是沒有 - 看看沒有先觸發其他種類的Listener ,ex:entryAdded
結果還是沒有 - 檢查是不是因為tryLock導致資料更新過程被省略
試過兩隻主程式一直互相執行trylock更新IMap,
但只會出現 tryLock failed,不會出現oldValue=null的狀況
後來發現問題出在有些程式碼更新map的資料使用效能較好的
void com.hazelcast.core.IMap.set(String key, DeviceStatus value)
根據api doc說明
Warning:
This method breaks the contract of EntryListener.
When an entry is updated by set(),
it fires an EntryEvent with a null oldValue.
實際測試程式碼 用set的方式的確不會取到oldValue
,所以改回get就修(?)好了
,最後改code的也不是我XD
雖然是從來沒有使用過set方法,
但看code的時候完全沒發現使用的方法不同,
只聚焦在是不是有做過刪除或是set null...
不太了解邏輯為什麼要這樣設計,
但是人家都寫在api doc上了
只好承認用api時很少把全方法跟api doc看完。
只好承認用api時很少把全方法跟api doc看完。
留言
張貼留言