任何人都可以用简单的话来解释Hibernate中的第一级和第二级缓存是什么?
答案 0 :(得分:285)
1.1)第一级缓存
第一级缓存始终与会话对象关联。 Hibernate默认使用此缓存。在这里,它处理一个 交易接连另一个,意味着不会处理多个交易 倍。主要是它减少了它需要的SQL查询的数量 在给定的交易中生成。那不是在之后更新 在事务中完成的每个修改,它都会更新事务 只在交易结束时。
1.2)二级缓存
二级缓存始终与会话工厂对象关联。在运行事务时,在它之间加载 会话工厂级别的对象,以便这些对象 可用于整个应用程序,不受单个用户的约束。以来 只要对象是,对象就已经加载到缓存中 查询返回,当时无需去数据库 交易。这样二级缓存就可以工作了。我们可以在这里使用 查询级缓存也。
答案 1 :(得分:114)
对Streamline Logic博客上的第一级缓存有一个非常好的解释。
基本上,第一级缓存是在每个会话的基础上进行的,因为第二级缓存可以在多个会话中共享。
答案 2 :(得分:97)
这里有一些关于hibernate缓存的基本解释......
第一级缓存与“会话”对象相关联。
缓存对象的范围是会话。会话关闭后,缓存的对象将永远消失。
默认情况下启用一级缓存,您无法禁用它。
当我们第一次查询实体时,它从数据库中检索并存储在与hibernate会话相关联的第一级缓存中。
如果我们使用相同的会话对象再次查询同一个对象,它将从缓存加载,并且不会执行sql查询。
可以使用evict()
方法从会话中删除加载的实体。如果使用evict()
方法删除了该实体,则下次加载该实体将再次进行数据库调用。
可以使用clear()
方法删除整个会话缓存。它将删除存储在缓存中的所有实体。
二级缓存与一级缓存不同,后者可在会话工厂范围内全局使用。
在会话工厂范围中创建二级缓存,并且可以在使用该特定会话工厂创建的所有会话中使用。
这也意味着一旦会话工厂关闭,与之关联的所有缓存就会消失,缓存管理器也会关闭。
每当hibernate会话尝试加载实体时,它首先在第一级缓存中寻找实体的缓存副本(与特定的hibernate会话相关联)。
如果实体的缓存副本存在于第一级缓存中,则它将作为load方法的结果返回。
如果第一级缓存中没有缓存实体,则查找第二级缓存以获取缓存实体。
如果二级缓存具有缓存实体,则它将作为load方法的结果返回。但是,在返回实体之前,它还存储在第一级缓存中,以便下一次调用实体的加载方法将从第一级缓存本身返回实体,并且不需要再次进入二级缓存。
如果在第一级缓存和第二级缓存中也找不到实体,则在作为load()
方法的响应返回之前,执行数据库查询并将实体存储在两个缓存级别中。
答案 3 :(得分:9)
Hibernate尝试将持久性上下文刷新推迟到最后可能的时刻。正如我在this article中所解释的那样,该策略传统上被称为事务后写。
后写与Hibernate刷新更相关,而不是任何逻辑或物理事务。在交易过程中,刷新可能会发生多次。
仅对当前数据库事务可见刷新的更改。在提交当前事务之前,其他并发事务看不到任何更改。
由于具有一级缓存,Hibernate可以进行一些优化:
一个合适的缓存解决方案必须跨越多个Hibernate会话,这就是Hibernate也支持附加的二级缓存的原因。
二级缓存绑定到SessionFactory生命周期,因此只有在SessionFactory
关闭时(通常是在应用程序关闭时),它才会被销毁。第二级缓存主要基于实体,尽管它也支持可选的查询缓存解决方案。
有关更多详细信息,请查看this article。
答案 4 :(得分:3)
默认情况下,NHibernate使用基于会话对象的第一级缓存。但是如果您在多服务器环境中运行,那么第一级缓存可能无法实现可扩展性以及一些性能问题。这是因为它必须经常访问数据库,因为数据分布在多个服务器上。换句话说,NHibernate提供了一个基本的,不那么复杂的进程内L1缓存。但是,它不提供缓存解决方案必须具有的对应用程序性能有显着影响的功能。
因此所有这些问题的问题是使用与会话工厂对象相关联的L2缓存。它减少了访问数据库的时间,因此最终增加了应用程序响应时间。
答案 5 :(得分:1)
第一级缓存
Session对象包含第一级缓存数据。它默认启用。第一级缓存数据将不可用于整个应用程序。应用程序可以使用许多会话对象。
二级缓存
SessionFactory对象包含第二级缓存数据。存储在二级缓存中的数据可供整个应用程序使用。但我们需要明确地启用它。
答案 6 :(得分:-4)
在二级缓存中,域hbm文件可以是密钥可变的,值为false。 例如, 在这个领域类中,一天中的一些持续时间作为普遍真理保持不变。因此,它可以在应用程序中标记为不可变。