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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate二级缓存

發(fā)布時(shí)間:2023/12/14 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate二级缓存 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

因?yàn)轫?xiàng)目中經(jīng)常出現(xiàn),由于使用了hibernate生成的方法,會(huì)從二級(jí)緩存中拿取數(shù)據(jù),導(dǎo)致數(shù)據(jù)不一致的問(wèn)題,甚至導(dǎo)致出現(xiàn)臟數(shù)據(jù)的問(wèn)題,所以總結(jié)以下hibernate的緩存機(jī)制。

什么是二級(jí)緩存

我們知道一級(jí)緩存,并且一級(jí)緩存的作用范圍就在session中,每個(gè)session都有一個(gè)自己的一級(jí)緩存,而二級(jí)緩存也就是比一級(jí)緩存的作用范圍更廣,存儲(chǔ)的內(nèi)容更多,我們知道session是由sesssionFactory創(chuàng)建出來(lái)的,一個(gè)sessionFactory能夠創(chuàng)建很多個(gè)session,每個(gè)session有自己的緩存,稱為一級(jí)緩存,而sessionFactory也有自己的緩存,存放的內(nèi)容供所有session共享,也就是二級(jí)緩存。?

 一級(jí)緩存:保存session中,事務(wù)范圍的緩存(通俗點(diǎn)講,就是session關(guān)閉后,該緩存就沒了,其緩存只能在session的事務(wù)開啟和結(jié)束之間使用)

 二級(jí)緩存:保存在SessionFactory,進(jìn)程范圍內(nèi)的緩存(進(jìn)程包括了多個(gè)線程,也就是我們上面說(shuō)的意思,A線程可能拿到一個(gè)session進(jìn)行操作,B線程也可能拿到一個(gè)session進(jìn)行操作,但是A和B讀能訪問(wèn)到SessionFactory中的緩存,也就是二級(jí)緩存,這里只是拿A,B說(shuō)事,可能有一個(gè)線程剛創(chuàng)建出來(lái)session,也能拿到二級(jí)緩存中的數(shù)據(jù))

hql做的查詢能夠存入一級(jí)緩存和二級(jí)緩存,但是不能夠從二級(jí)緩存中拿數(shù)據(jù)

get\load能夠?qū)⑵洳樵償?shù)據(jù)插入一級(jí)緩存和二級(jí)緩存,也能夠從一級(jí)二級(jí)緩存中拿數(shù)據(jù)。

例如:

我們有一個(gè)Order對(duì)象,是一個(gè)實(shí)體對(duì)象,對(duì)應(yīng)數(shù)據(jù)庫(kù)中order表中的一條記錄,經(jīng)過(guò)查詢已有n個(gè)Order對(duì)象被放入二級(jí)緩存中。現(xiàn)在我們要修改order表中任意任x條記錄,執(zhí)行以下HQL:

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

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

二級(jí)緩存的更新機(jī)制

 存放了對(duì)于查詢結(jié)果相關(guān)的表進(jìn)行插入,更新,刪除操作的時(shí)間戳,Hibernate通過(guò)時(shí)間戳緩存區(qū)域來(lái)判斷被緩存的查詢結(jié)果是否過(guò)期,如果過(guò)期了則從數(shù)據(jù)庫(kù)中拿數(shù)據(jù),沒過(guò)期則直接從緩存中拿數(shù)據(jù)。通俗點(diǎn)講,就三步

1、查詢結(jié)果放到二級(jí)緩存中,此時(shí)記錄一個(gè)時(shí)間為T1

2、當(dāng)有操作直接更改了數(shù)據(jù)庫(kù)的數(shù)據(jù)時(shí),比如使用hql語(yǔ)句,就會(huì)直接對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改,而不會(huì)改變緩存中的數(shù)據(jù)。此時(shí)記錄時(shí)間為T2

3、當(dāng)下次在查詢記錄時(shí),會(huì)先將T1和T2進(jìn)行比較,如果T2>T1,則說(shuō)明緩存中的數(shù)據(jù)不是最新的,那么就從數(shù)據(jù)庫(kù)中拿出正確的數(shù)據(jù),如果T2<T1,就說(shuō)明沒有對(duì)數(shù)據(jù)庫(kù)進(jìn)行過(guò)什么修改操作,那么就可以直接從緩存中獲取數(shù)據(jù)。

解惑:如果沒有T1和T2的比較,那么會(huì)出現(xiàn)我們查詢到的數(shù)據(jù)不是準(zhǔn)確的,因?yàn)榫拖裆厦娴诙剿f(shuō)的,數(shù)據(jù)庫(kù)的數(shù)據(jù)會(huì)和緩存中的數(shù)據(jù)不一樣,什么都不做就從緩存中拿數(shù)據(jù),就會(huì)出現(xiàn)錯(cuò)誤。

這里需要注意:如果你用了update語(yǔ)句,那么二級(jí)緩存無(wú)法更新。因?yàn)橄到y(tǒng)無(wú)法判斷二級(jí)緩存的對(duì)象哪些失效了。如果你是update(對(duì)象)的方式更新,則系統(tǒng)可以通過(guò)ID確認(rèn)哪個(gè)二級(jí)緩存對(duì)象需要更新,系統(tǒng)能夠維護(hù)二級(jí)緩存。

項(xiàng)目中出現(xiàn)的緩存問(wèn)題分析

由于項(xiàng)目的beta和prod環(huán)境是有多臺(tái)server集群的,所以如果在某些對(duì)數(shù)據(jù)一致性要求較高的地方使用了二級(jí)緩存(也就是從緩存中取數(shù)據(jù),不是直接從db中查取數(shù)據(jù)),就會(huì)出現(xiàn)數(shù)據(jù)一致性問(wèn)題。

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

上面這種情況當(dāng)清楚的db的catch之后就可以恢復(fù)正常,但還有一種更嚴(yán)重的情況,如果用戶A從緩存中獲取的和db不一致的數(shù)據(jù),并做的相應(yīng)的更新操作,那么就會(huì)直接導(dǎo)致數(shù)據(jù)庫(kù)出現(xiàn)臟數(shù)據(jù),直接導(dǎo)致這個(gè)用戶出現(xiàn)問(wèn)題。

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

?

?

?

總結(jié)

以上是生活随笔為你收集整理的Hibernate二级缓存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。