關(guān)于spring data jpa一級(jí)緩存的問(wèn)題
spring data jpa一級(jí)緩存
jpa更新數(shù)據(jù),數(shù)據(jù)庫(kù)更新了,但是查詢出來(lái)的還是更新前的問(wèn)題,這是因?yàn)閖pa的一級(jí)緩存,查詢默認(rèn)是從緩存中查詢的,而不是從DB查詢。
解決辦法
repository
update方法上加入@Modifying(clearAutomatically = true)即可,它更新完數(shù)據(jù)庫(kù)后會(huì)主動(dòng)清理一級(jí)緩存,但我用了好像沒(méi)什么效果,可能使用方法不對(duì),建議使用下面這個(gè)
entityManager對(duì)象
通過(guò) em.clear(); 在每次查詢前清除 JPA 緩存
spring data jpa的那些坑
springdatajpa是持久化框架,底層是hibernate實(shí)現(xiàn)的,基本原理與hibernate一致。
hibernate緩存機(jī)制
Hibernate的一級(jí)緩存就是指Session緩存,此Session非http的session會(huì)話技術(shù),可以理解為JDBC的Connection,連接會(huì)話,Session緩存就是一塊內(nèi)存空間,用來(lái)存放相互管理的java對(duì)象,在使用Hibernate查詢對(duì)象的時(shí)候,首先使用對(duì)象的OID(ObjectID)
在Hibernate的一級(jí)緩存空間進(jìn)行查找,如果通過(guò)OID匹配到了對(duì)象,就直接從一級(jí)緩存中取出使用,如果沒(méi)有找到匹配該OID值的對(duì)象,這才會(huì)進(jìn)行查詢數(shù)據(jù)庫(kù)。
當(dāng)從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù)的時(shí)候,該數(shù)據(jù)就會(huì)被放入到Session緩存中,目的就是為了減少數(shù)據(jù)庫(kù)的訪問(wèn)次數(shù),從而提高性能
特點(diǎn)
- 當(dāng)應(yīng)用程序調(diào)用Session接口的 save(), update(), saveOrUpdate() 時(shí)候,如果緩存中沒(méi) 有相應(yīng)的對(duì)象,Hb就會(huì)自動(dòng)的把查詢信息加入到緩存。
- 當(dāng)應(yīng)用程序調(diào)用Session接口的 load(), get(), list() 等查詢方法的時(shí)候,會(huì)進(jìn)行判斷緩存中是否有數(shù)據(jù),同摘要。
- 當(dāng)應(yīng)用程序調(diào)用Session接口的 close() Session緩存會(huì)被清空
案例
public void demo1 (){ Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); User user1 = session.get(User.class, "1"); System.out.println(user1); System.out.println("-------------"); User user2 = session.get(User.class, "1"); System.out.println(user2); System.out.println(user1 == user2); transaction.commit(); session.close(); }
我們發(fā)現(xiàn)第一次執(zhí)行Session的get()方法的時(shí)候,由于一級(jí)緩存中沒(méi)有數(shù)據(jù),所以會(huì)向數(shù)據(jù)庫(kù)發(fā)送一條sql語(yǔ)句進(jìn)行查詢,第二次調(diào)用get()的時(shí)候,則不會(huì)發(fā)送sql語(yǔ)句,而是從一級(jí)緩存中取的,所以u(píng)ser和user2的內(nèi)存地址相等
一級(jí)緩存的快照區(qū)
Hibernate向一級(jí)緩存放入數(shù)據(jù)的時(shí)候,同時(shí)復(fù)制一份放到Hibernate快照中,當(dāng)使用commot()提交事務(wù)的時(shí)候,同時(shí)會(huì)清理Session的一級(jí)緩存,這是會(huì)用OID判斷一級(jí)緩存中的對(duì)象和快照中的對(duì)象是否一致,如果一致則執(zhí)行update 語(yǔ)句,將緩存中的內(nèi)容同步到數(shù)據(jù)庫(kù),并且更新快照,這也就實(shí)現(xiàn)了不使用 update 語(yǔ)句就可以自動(dòng)更新數(shù)據(jù)庫(kù),Hibernate快照的作用也就是為了保持緩存中的數(shù)據(jù)和數(shù)據(jù)庫(kù)中的數(shù)據(jù)的一致性。
線上坑案例
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java如何解決發(fā)送Post請(qǐng)求報(bào)Stream?closed問(wèn)題
這篇文章主要介紹了Java如何解決發(fā)送Post請(qǐng)求報(bào)Stream?closed問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06SpringCloud之監(jiān)控?cái)?shù)據(jù)聚合Turbine的實(shí)現(xiàn)
這篇文章主要介紹了SpringCloud之監(jiān)控?cái)?shù)據(jù)聚合Turbine的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Java實(shí)現(xiàn)SSL雙向認(rèn)證的方法
這篇文章主要介紹了Java實(shí)現(xiàn)SSL雙向認(rèn)證的方法,實(shí)例分析了ssl認(rèn)證的原理與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-08-08struts2通過(guò)action返回json對(duì)象
struts2通過(guò)action返回json對(duì)象其實(shí)很簡(jiǎn)單的,首先我們需要引入jar包,然后在寫一個(gè)簡(jiǎn)單的action就好了,接下來(lái)通過(guò)本文給大家介紹struts2通過(guò)action返回json對(duì)象的方法,感興趣的朋友一起看看吧2016-09-09解決SpringBoot log4j日志沒(méi)生成的問(wèn)題
這篇文章主要介紹了解決SpringBoot log4j日志沒(méi)生成的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07springboot利用AOP完成日志統(tǒng)計(jì)的詳細(xì)步驟
項(xiàng)目用到了過(guò)濾器,可能有的人會(huì)不理解,之所以用過(guò)濾器是因?yàn)橄胍谌罩居涗沺ost請(qǐng)求的json數(shù)據(jù)。本文重點(diǎn)給大家介紹springboot利用AOP完成日志統(tǒng)計(jì)的詳細(xì)步驟,感興趣的朋友跟隨小編一起看看吧2021-12-12java 出現(xiàn)問(wèn)題javax.servlet.http.HttpServlet was not found解決方法
這篇文章主要介紹了java 出現(xiàn)問(wèn)題javax.servlet.http.HttpServlet was not found解決方法的相關(guān)資料,需要的朋友可以參考下2016-11-11SpringBoot如何使用applicationContext.xml配置文件
這篇文章主要介紹了SpringBoot使用applicationContext.xml配置文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06Java實(shí)現(xiàn)導(dǎo)出合并Excel單元格
隨著數(shù)據(jù)的不斷增長(zhǎng),很多時(shí)候需要將數(shù)據(jù)導(dǎo)出到Excel中進(jìn)行分析、處理和展示。本文將介紹如何使用Java實(shí)現(xiàn)Excel導(dǎo)出,并且可以合并單元格,需要的可以參考一下2023-04-04