java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > spring data jpa一级缓存

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

作者: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缓存中,目的就是为了减少数据库的访问次数,从而提高性能

特点

案例

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

线上坑案例

总结

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

您可能感兴趣的文章:
阅读全文