关于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快照的作用也就是为了保持缓存中的数据和数据库中的数据的一致性。

线上坑案例

总结

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

相关文章

  • IDEA实现JDBC的操作步骤

    IDEA实现JDBC的操作步骤

    JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,本文给大家介绍IDEA实现JDBC的操作步骤,感兴趣的朋友一起看看吧
    2022-01-01
  • 使用Spring Boot+MyBatis框架做查询操作的示例代码

    使用Spring Boot+MyBatis框架做查询操作的示例代码

    这篇文章主要介绍了使用Spring Boot+MyBatis框架做查询操作的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • springboot 项目启动后无日志输出直接结束的解决

    springboot 项目启动后无日志输出直接结束的解决

    这篇文章主要介绍了springboot 项目启动后无日志输出直接结束的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • JavaWeb项目打开网页出现Session Error的异常解决方案

    JavaWeb项目打开网页出现Session Error的异常解决方案

    这篇文章主要介绍了JavaWeb项目打开网页出现Session Error的异常解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java Optional解决空指针异常总结(java 8 功能)

    Java Optional解决空指针异常总结(java 8 功能)

    这篇文章主要介绍了Java Optional解决空指针异常总结(java 8 功能),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • SpringBoot 整合线程池的示例详解

    SpringBoot 整合线程池的示例详解

    线程池是一种利用池化技术思想来实现的线程管理技术,主要是为了复用线程、便利地管理线程和任务、并将线程的创建和任务的执行解耦开来,这篇文章主要介绍了SpringBoot 整合线程池的示例详解,需要的朋友可以参考下
    2024-08-08
  • Java 栈和队列的相互转换详解

    Java 栈和队列的相互转换详解

    栈和队列,严格意义上来说,也属于线性表,因为它们也都用于存储逻辑关系为 "一对一" 的数据,但由于它们比较特殊,因此将其单独作为一章,做重点讲解
    2022-02-02
  • java垃圾回收原理之GC算法基础

    java垃圾回收原理之GC算法基础

    本章简要介绍GC的基本原理和相关技术, 下一章节再详细讲解GC算法的具体实现。各种垃圾收集器的实现细节虽然并不相同,但总体而言,垃圾收集器都专注于两件事情:查找所有存活对象,抛弃其他的部分,即死对象,不再使用的对象
    2022-01-01
  • Spring MVC简介_动力节点Java学院整理

    Spring MVC简介_动力节点Java学院整理

    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。今天先从写一个Spring MVC的HelloWorld开始,让我们看看如何搭建起一个Spring mvc的环境并运行程序,感兴趣的朋友一起学习吧
    2017-08-08
  • 使用java批量写入环境变量的实现

    使用java批量写入环境变量的实现

    本文主要介绍了使用java批量写入环境变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03

最新评论