我很难理解hibernate何时命中二级缓存以及何时使缓存无效.
这就是我目前所理解的:
我不明白的是
或者我认为缓存完全错误?在这种情况下,哪种更适合使用二级缓存?hibernate文档根本不清楚缓存如何在现实中工作.只有如何设置它的说明.
更新: 所以我已经明白二级缓存(没有查询缓存)对于按ID加载数据会很好.例如,我有用户对象,我想检查Web应用程序中每个请求的权限.通过在二级缓存中缓存用户来减少数据库访问是否是一个好例子?就像我将用户ID存储在会话中或我需要检查权限的任何地方,我会通过它的id加载用户并检查权限.
我正致力于使用Spring 3和Hibernate 3.6开发Web应用程序.目前我试图了解如何使用Spring和Hibernate进行缓存.我找到了一些关于使用Hibernate缓存的消息来源以及一些关于Spring的消息,我现在尝试将我的信息结合在一起.我仍然对这两个框架都有一些问题,如果有人能够回答它们或告诉我这里列出的事实是否正确,我会很高兴.
大多数时候,简短的答案(是/否)就足够了.我认为这个列表对其他人也很有用,他们想要了解spring和hibernate的缓存是如何工作的.
General
1) Hibernate支持以下缓存:第一级缓存,第二级缓存,查询缓存
2) Spring本身支持以下缓存可能性:只是方法缓存
1st Level Cache
3)第一级缓存是每个Hibernate应用程序的一部分.
4)为每个休眠会话创建第一级缓存.
5)第一级缓存中保存了什么?对象或只是其属性的值?查询及其结果?
2nd Level Cache
6)我发现:每个应用程序使用ONCE二级缓存.那不是假的吗?是不是每次sessionfactory使用ONCE?和:多个sessionfactorys =多个第二级缓存可能吗?
7)在二级缓存中保存的内容:在我看来,只是属于一条记录的值,而不是对象本身.
8)当存储来自二级缓存中的一个记录的值时,它是否可以存储相关值(来自通过外键连接的对象)?
9)更新二级缓存中一个对象的值时,是否可以更新缓存中与其连接的对象的值?
10)当一个对象的值发生变化时,如何更新二级缓存?冲洗?我可以只更新缓存的一部分,还是必须更新整个缓存?
11)二级缓存在哪里有意义,哪里不存在?
12)缓存模式:每个缓存模式都提供不同的缓存策略吗?例如,对于缓存模式"只读",不需要同步数据库和缓存吗?其他缓存模式是否提供同步?我认为同步必须由开发者自己完成?
SessionFactory
13)查询缓存和二级缓存有什么区别?在我看来:在查询缓存中,结果集被保存,但没有使用它们的值,只有它们的ID.当再次使用查询并且结果集仍然"正确"时,将从二级缓存中查询属于id的值
14)对于查询缓存,必须使用二级缓存?
15)查询缓存哪里有意义,哪里不存在?
Query Cache
16) Spring是否提供了比方法缓存更多的缓存可能性?
17)方法缓存没有与hibernate缓存相关联
18)但是:对于方法缓存,第二级是必要的,比如ehcache(也可以被hibernate使用)
19)可以在没有数据库查询的情况下使用方法缓存吗?
Spring
20)如果使用ehcache作为二级缓存的hibernate和用于方法缓存的spring的ehcache,我可以使用相同的ehcache-instance吗?是否有可能混淆了什么?
21)当使用第一级缓存和第二级缓存时,它们会混淆吗?在查询数据库时,结果来自哪里,第一级或第二级缓存?第一级缓存是否与二级缓存一起使用?
22)其他任何可以通过使用我提到的缓存混淆的东西?:-)
谢谢你的回答,不管是什么问题!:-)
我正在使用带有JPA2的Spring Boot 1.2.5来注释实体(并将hibernate作为JPA实现的底层).
我想在该设置中使用二级缓存,因此实体使用了注释 @javax.persistence.Cacheable
我还在application.properties中添加了以下内容:
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
Run Code Online (Sandbox Code Playgroud)
在启动期间,hibernate抱怨缺乏,EhCacheRegionFactory所以我也把它添加到pom:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
但仍然是查询类似于entityManager.find(Clazz.class, pk)触发数据库查询而不是使用缓存数据.
知道缺少什么吗?
我们有一个使用Hibernate的二级缓存来避免数据库命中的应用程序.
我想知道当一个外部进程如MySQL管理员直接连接修改数据库(更新/插入/删除)时,是否有一些简单的方法可以使Java应用程序的Hibernate二级缓存无效.
我们使用EHCache作为我们的二级缓存实现.
我们混合使用@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)和@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE),并且我们没有在每个实体上使用时间戳启用Optimistic并发控制.
SessionFactory包含管理二级缓存的方法: - 管理缓存
sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class); //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
Run Code Online (Sandbox Code Playgroud)
但是因为我们使用@Cache注释单个实体类,所以我们没有"可靠"(例如没有手动步骤)将其添加到列表的中心位置.
// Easy to forget to update this to properly evict the class
public static final Class[] cachedEntityClasses = {Cat.class, Dog.class, Monkey.class}
public void clear2ndLevelCache() {
SessionFactory sessionFactory = ... //Retrieve SessionFactory
for (Class entityClass : cachedEntityClasses) {
sessionFactory.evict(entityClass);
}
}
Run Code Online (Sandbox Code Playgroud)
Hibernate的二级缓存没有真正的方法来知道数据库中的实体发生了变化,除非它查询该实体(缓存正在保护您的实体).因此,作为一种解决方案,我们可以简单地调用一些方法来强制二级缓存驱逐一切(再次因为缺乏锁定和并发控制,您可能会因"读取"或更新过时数据而导致进程中的事务风险).
我刚开始考虑在我的一个应用程序中使用NHibernate二级缓存.我可能会使用NHibernate.Caches.SysCache.SysCacheProvider依赖于ASP.net缓存的.
启用缓存不是问题,但我想知道如何管理缓存,例如以编程方式从缓存中删除某些实体等.
我的应用程序是某种图像数据库.用户通过后端上传图像,并可以通过访问在前端查看图像/ImageDb/Show?userId=someUserId
数据不会经常变化.如果它发生变化,用户在后端的名为"清除我的缓存"的按钮无关紧要,该按钮会从缓存中删除此用户的缓存对象.
我在网上找到了一个可以从nhibernates二级缓存中删除所有缓存对象的解决方案.但这对我来说有点太暴力了......我不想为几十个用户清除整个缓存,因为一个用户试图清除缓存中的自己的数据.
所以我基本上想做的是:有选择地从C#中的nhibernates二级缓存中删除缓存的db对象.
这可能吗?我想这也取决于缓存提供商.如果ASP.net缓存提供程序无法做到这一点,我可以使用其他内置/开源建议.
我希望通过代码清除NHibernate中的整个二级缓存.有没有办法做这个独立于正在使用的缓存提供程序?(我们让客户在同一个应用程序中同时使用memcache和syscache).
我们希望清除整个缓存,因为数据库外部可能已发生更改(我们无法保证:哪些表/实体受到影响,因此我们必须假设最坏).
现代数据库提供缓存支持.大多数ORM框架也会缓存检索到的数据.为什么这种重复是必要的?
我该如何决定CacheConcurrencyStrategy使用哪个?
NonstrictReadWriteCache,ReadOnlyCache,ReadWriteCache,TransactionalCache.我阅读了https://www.hibernate.org/hib_docs/v3/api/org/hibernate/cache/CacheConcurrencyStrategy.html,但没有详细解释.
将EhCache v2.4.5配置为hibernate v3.6.7的二级缓存后,在尝试使用hibernate会话加载特定实体的所有对象时出现以下错误.(第一次加载对象没有错误)
java.lang.IllegalStateException: The country Cache is not alive.
at net.sf.ehcache.Cache.checkStatus(Cache.java:2438)
at net.sf.ehcache.Cache.get(Cache.java:1541)
at net.sf.ehcache.hibernate.regions.EhcacheTransactionalDataRegion.get(EhcacheTransactionalDataRegion.java:105)
at net.sf.ehcache.hibernate.strategy.AbstractReadWriteEhcacheAccessStrategy.putFromLoad(AbstractReadWriteEhcacheAccessStrategy.java:90)
at net.sf.ehcache.hibernate.nonstop.NonstopAwareEntityRegionAccessStrategy.putFromLoad(NonstopAwareEntityRegionAccessStrategy.java:180)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:195)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
at org.hibernate.loader.Loader.doQuery(Loader.java:857)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2533)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
at dataAccess.CountryDAO.loadAll(CountryDAO.java:80)
Run Code Online (Sandbox Code Playgroud)
我的hibernate配置是:
<property name="hibernate.cache.region.factory_class">
net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
</property>
<property name="hibernate.cache.provider_configuration">
/ehcache.xml
</property>
<property name="hibernate.cache.use_second_level_cache">
true
</property>
<property name="hibernate.cache.use_query_cache">
true
</property>
Run Code Online (Sandbox Code Playgroud)
我的EhCache配置是:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<transactionManagerLookup
class="net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup"
properties="jndiName=java:/TransactionManager" propertySeparator=";" />
<cacheManagerEventListenerFactory
class="" properties="" />
<defaultCache maxElementsInMemory="0" …Run Code Online (Sandbox Code Playgroud) hibernate ×8
caching ×5
ehcache ×4
java ×4
database ×2
nhibernate ×2
orm ×2
isession ×1
jpa-2.0 ×1
memcached ×1
spring ×1
spring-boot ×1
syscache2 ×1
transactions ×1