日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate二级缓存

發布時間:2023/12/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate二级缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

因為項目中經常出現,由于使用了hibernate生成的方法,會從二級緩存中拿取數據,導致數據不一致的問題,甚至導致出現臟數據的問題,所以總結以下hibernate的緩存機制。

什么是二級緩存

我們知道一級緩存,并且一級緩存的作用范圍就在session中,每個session都有一個自己的一級緩存,而二級緩存也就是比一級緩存的作用范圍更廣,存儲的內容更多,我們知道session是由sesssionFactory創建出來的,一個sessionFactory能夠創建很多個session,每個session有自己的緩存,稱為一級緩存,而sessionFactory也有自己的緩存,存放的內容供所有session共享,也就是二級緩存。?

 一級緩存:保存session中,事務范圍的緩存(通俗點講,就是session關閉后,該緩存就沒了,其緩存只能在session的事務開啟和結束之間使用)

 二級緩存:保存在SessionFactory,進程范圍內的緩存(進程包括了多個線程,也就是我們上面說的意思,A線程可能拿到一個session進行操作,B線程也可能拿到一個session進行操作,但是A和B讀能訪問到SessionFactory中的緩存,也就是二級緩存,這里只是拿A,B說事,可能有一個線程剛創建出來session,也能拿到二級緩存中的數據)

hql做的查詢能夠存入一級緩存和二級緩存,但是不能夠從二級緩存中拿數據

get\load能夠將其查詢數據插入一級緩存和二級緩存,也能夠從一級二級緩存中拿數據。

例如:

我們有一個Order對象,是一個實體對象,對應數據庫中order表中的一條記錄,經過查詢已有n個Order對象被放入二級緩存中。現在我們要修改order表中任意任x條記錄,執行以下HQL:

template.bulkUpdate("update Order set owner = ? where id in (?,?,?)");

?這時Hibernate會直接將二級緩存中的n個Order對象清除掉。 天啊,居然不是你想像的修改誰就同步更新二級緩存中的誰,而是清除了二級緩存中全部的Order類型的對象。為什么?這一切是為了保證“數據一致性”。你執行了HQL修改了order表中的x條記錄,這x條是哪幾條?如果sql是子查詢:update Order set owner =? where id in(select id from *** ),誰知道你修改了order表中的哪幾條記錄,你自己都不知道,Hibernate更不知道了。所以為了保證二級緩存中的數據與order表中的數據一致,只能清除了二級緩存中全部的Order類型的對象。二級緩存頻繁的載入與清除,這樣緩存命中率就會下降。

二級緩存的更新機制

 存放了對于查詢結果相關的表進行插入,更新,刪除操作的時間戳,Hibernate通過時間戳緩存區域來判斷被緩存的查詢結果是否過期,如果過期了則從數據庫中拿數據,沒過期則直接從緩存中拿數據。通俗點講,就三步

1、查詢結果放到二級緩存中,此時記錄一個時間為T1

2、當有操作直接更改了數據庫的數據時,比如使用hql語句,就會直接對數據庫進行修改,而不會改變緩存中的數據。此時記錄時間為T2

3、當下次在查詢記錄時,會先將T1和T2進行比較,如果T2>T1,則說明緩存中的數據不是最新的,那么就從數據庫中拿出正確的數據,如果T2<T1,就說明沒有對數據庫進行過什么修改操作,那么就可以直接從緩存中獲取數據。

解惑:如果沒有T1和T2的比較,那么會出現我們查詢到的數據不是準確的,因為就像上面第二步所說的,數據庫的數據會和緩存中的數據不一樣,什么都不做就從緩存中拿數據,就會出現錯誤。

這里需要注意:如果你用了update語句,那么二級緩存無法更新。因為系統無法判斷二級緩存的對象哪些失效了。如果你是update(對象)的方式更新,則系統可以通過ID確認哪個二級緩存對象需要更新,系統能夠維護二級緩存。

項目中出現的緩存問題分析

由于項目的beta和prod環境是有多臺server集群的,所以如果在某些對數據一致性要求較高的地方使用了二級緩存(也就是從緩存中取數據,不是直接從db中查取數據),就會出現數據一致性問題。

原因:由于server的elb機制是粘性session,那么就可能出現用戶A和admin連上了兩臺不同的server,并且所有的db操作都是在不同的server上進行的,這時候如果admin更新的用戶A的狀態信息,只會刷新admin所連接server的二級緩存,并不會刷新其他server的緩存,而用戶A并不能及時獲取到db的更新,如果所有的地方都是從二級緩存中取數據就還好,只會出現延時的問題,這種可能性比較小。但如果不是全部都從二級緩存中取數據,那用戶A就會出現數據不一致問題,甚至導致頁面掛掉。

上面這種情況當清楚的db的catch之后就可以恢復正常,但還有一種更嚴重的情況,如果用戶A從緩存中獲取的和db不一致的數據,并做的相應的更新操作,那么就會直接導致數據庫出現臟數據,直接導致這個用戶出現問題。

所以hibernate需要慎用,在更新較為頻繁或者對數據一致性較高的地方不要使用二級緩存,否則會得不償失。

?

?

?

總結

以上是生活随笔為你收集整理的Hibernate二级缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。