关于spring data jpa一级缓存的问题

 更新时间:2023年11月30日 14:58:10   作者:TheNether  
这篇文章主要介绍了关于spring data jpa一级缓存的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

spring data jpa一级缓存

jpa更新数据,数据库更新了,但是查询出来的还是更新前的问题,这是因为jpa的一级缓存,查询默认是从缓存中查询的,而不是从DB查询。

解决办法

repository

update方法上加入@Modifying(clearAutomatically = true)即可,它更新完数据库后会主动清理一级缓存,但我用了好像没什么效果,可能使用方法不对,建议使用下面这个

entityManager对象

通过 em.clear(); 在每次查询前清除 JPA 缓存

spring data jpa的那些坑

springdatajpa是持久化框架,底层是hibernate实现的,基本原理与hibernate一致。

hibernate缓存机制

Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Session缓存就是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先使用对象的OID(ObjectID)

在Hibernate的一级缓存空间进行查找,如果通过OID匹配到了对象,就直接从一级缓存中取出使用,如果没有找到匹配该OID值的对象,这才会进行查询数据库。

当从数据库中查询数据的时候,该数据就会被放入到Session缓存中,目的就是为了减少数据库的访问次数,从而提高性能

特点

  • 当应用程序调用Session接口的 save(), update(), saveOrUpdate() 时候,如果缓存中没 有相应的对象,Hb就会自动的把查询信息加入到缓存。
  • 当应用程序调用Session接口的 load(), get(), list() 等查询方法的时候,会进行判断缓存中是否有数据,同摘要。
  • 当应用程序调用Session接口的 close() Session缓存会被清空

案例

   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();
	}

我们发现第一次执行Session的get()方法的时候,由于一级缓存中没有数据,所以会向数据库发送一条sql语句进行查询,第二次调用get()的时候,则不会发送sql语句,而是从一级缓存中取的,所以user和user2的内存地址相等

一级缓存的快照区

Hibernate向一级缓存放入数据的时候,同时复制一份放到Hibernate快照中,当使用commot()提交事务的时候,同时会清理Session的一级缓存,这是会用OID判断一级缓存中的对象和快照中的对象是否一致,如果一致则执行update 语句,将缓存中的内容同步到数据库,并且更新快照,这也就实现了不使用 update 语句就可以自动更新数据库,Hibernate快照的作用也就是为了保持缓存中的数据和数据库中的数据的一致性。

线上坑案例

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java如何解决发送Post请求报Stream closed问题

    Java如何解决发送Post请求报Stream closed问题

    这篇文章主要介绍了Java如何解决发送Post请求报Stream closed问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • SpringCloud之监控数据聚合Turbine的实现

    SpringCloud之监控数据聚合Turbine的实现

    这篇文章主要介绍了SpringCloud之监控数据聚合Turbine的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java实现SSL双向认证的方法

    Java实现SSL双向认证的方法

    这篇文章主要介绍了Java实现SSL双向认证的方法,实例分析了ssl认证的原理与相关实现技巧,需要的朋友可以参考下
    2016-08-08
  • struts2通过action返回json对象

    struts2通过action返回json对象

    struts2通过action返回json对象其实很简单的,首先我们需要引入jar包,然后在写一个简单的action就好了,接下来通过本文给大家介绍struts2通过action返回json对象的方法,感兴趣的朋友一起看看吧
    2016-09-09
  • 解决SpringBoot log4j日志没生成的问题

    解决SpringBoot log4j日志没生成的问题

    这篇文章主要介绍了解决SpringBoot log4j日志没生成的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java 设计模式之适配器模式详解

    Java 设计模式之适配器模式详解

    设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性
    2021-11-11
  • springboot利用AOP完成日志统计的详细步骤

    springboot利用AOP完成日志统计的详细步骤

    项目用到了过滤器,可能有的人会不理解,之所以用过滤器是因为想要在日志记录post请求的json数据。本文重点给大家介绍springboot利用AOP完成日志统计的详细步骤,感兴趣的朋友跟随小编一起看看吧
    2021-12-12
  • java 出现问题javax.servlet.http.HttpServlet was not found解决方法

    java 出现问题javax.servlet.http.HttpServlet was not found解决方法

    这篇文章主要介绍了java 出现问题javax.servlet.http.HttpServlet was not found解决方法的相关资料,需要的朋友可以参考下
    2016-11-11
  • SpringBoot如何使用applicationContext.xml配置文件

    SpringBoot如何使用applicationContext.xml配置文件

    这篇文章主要介绍了SpringBoot使用applicationContext.xml配置文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java实现导出合并Excel单元格

    Java实现导出合并Excel单元格

    随着数据的不断增长,很多时候需要将数据导出到Excel中进行分析、处理和展示。本文将介绍如何使用Java实现Excel导出,并且可以合并单元格,需要的可以参考一下
    2023-04-04

最新评论