2012-07-31 91 views
1


在这个问题上,我一直在撞墙撞墙。休眠Infinispan实体/查询缓存

我们正试图使用​​Infinispan实现Hibernate的二级缓存。该应用程序在JBoss AS 6上运行,并使用JTA事务。

在我们的persistence.xml我们:

... 
<!-- JTA configurations --> 
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" /> 
<property name="current_session_context_class" value="jta" /> 

<!-- Infinispan configurations --> 
<property name="hibernate.cache.use_second_level_cache" value="true" /> 
<property name="hibernate.cache.use_query_cache" value="true" /> 

<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/> 
<property name="hibernate.cache.infinispan.cachemanager" value="java:CacheManager/entity"/> 
... 

定义here:

在我们理解这是种缓存,我们需要为了做到以下几点:

使用案例一: 我们在数据库上有记录,它将保存参考数据。这些数据不会长时间改变(我们希望:))。

我们希望缓存这些记录,因为它们很可能会被查询。而当用户查询这些数据时,不需要去数据库,因为它应该被缓存。

对于这种情况,缓存类型是查询缓存还是实体缓存?作为查询总是相同的,我理解它的查询缓存作为查询应始终返回相同的结果。

我的查询:

List<MyEntity> list = session.createCriteria(MyEntity.class) 
     .add(Restrictions.eq("id", 1)) 
     .setCacheable(true) 
     .list(); 

使用案例二: 用户得到从数据库中的特定记录,他可能会对其进行更新。我们希望将此实体(或实体列表)保存在用户的会话(登录会话)缓存中,因此如果他在客户端上更新了此实体,我们不需要在更新之前进行选择。 在这种情况下,因为我们正在保存特定的实体,所以它被认为是实体缓存,对吧?如果我们要存储

为此,我们正在使用:

@Cacheable (true) 
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) 
public class MyEntity implements Serializable 
{ 
... 
} 

上午我做正确的这些假设?如果不是,这里有什么方法?我觉得我正在做一个很大的混乱。

回答

1

第二级(实体)缓存基于id作为关键字(使其更简单)。因此,每当参考数据在其他实体中被“引用”时,实体管理器在去DB之前首先检查它是否存在于缓存中。

查询缓存是查询结果(ids)实体的缓存。然后根据ID检索相应的实体(最好从实体缓存中...),因此您需要将实体缓存在二级缓存中才能有用。

对于您的第一个用例,引用数据:您应该将该实体标注为可缓存并使用只读策略。实体管理器将在加载时将引用数据放入引用实体中,或者使用find(clazz,id)从第二级缓存中获取引用数据。

情况2有点棘手。没有“会话”作用域缓存(如果需要将中间结果绑定到用户会话,则需要通过SFSB或任何上级会话机制来管理它自己)。如果你让实体可以缓存,它将被缓存给服务器上的每个用户,实体管理器上下文与用户没有直接的联系。

如果要防止在更新之前进行选择,则应该通过扩展持久性上下文阻止实体达到非托管状态(以防止合并)。如果实体通常可以由多个用户更新,则缓存可能会降低性能,因为管理一致性需要花费更多时间。

如果您遇到性能问题,那么您应该首先查看相关的实体获取和传播注释,如果它们太大,您向数据库发出请求或/和更新太多数据。

+0

我仍然试图吸收你所有的答案。我还有一个问题。对于我的第一个用例,如果我将另一个引用数据对象(记录)添加到数据库(使用相同的应用程序)会发生什么?缓存是否知道查询的结果已更改,下一次进行选择时,它会转到数据库吗? – 2012-07-31 17:05:56

+0

我不知道它是否会在它持续存在时将其放入缓存中。可能它会做出选择,因为触发器可能会导致数据更改。任何方式最多只能选择一个,然后放入缓存中。 – Kazaag 2012-07-31 20:10:20

+0

你可以在这篇文章中找到更多细节:http://www.javalobby.org/java/forums/t48846.html – Kazaag 2012-07-31 20:10:52