Hibernate缓存策略

38

以上已经涵盖了差异的要点。但是坦白地说,当我阅读API或文档时,我仍然无法清楚地理解这些差异。请查看我的帖子此处,其中更详细地描述了这些差异。请查看并随意评论。 - Achow
4个回答

65

Hibernate文档在定义它们时做得相当不错:

19.2.2. 策略:只读

如果您的应用程序需要读取,而不是修改持久化类的实例,则可以使用只读缓存。这是最简单和最优化的性能策略,即使在集群中使用也是安全的。

19.2.3. 策略:读/写

如果应用程序需要更新数据,则可能适合使用读/写缓存。如果需要序列化事务隔离级别,则永远不应使用此缓存策略。如果在JTA环境中使用缓存,则必须指定属性hibernate.transaction.manager_lookup_class,并命名用于获取JTA TransactionManager的策略。在其他环境中,您应确保当调用Session.close()Session.disconnect()时完成事务。如果要在集群中使用此策略,则应确保底层缓存实现支持锁定。内置缓存提供程序不支持锁定。

19.2.4. 策略:非严格读/写

如果应用程序仅偶尔需要更新数据(即极不可能有两个事务同时尝试更新同一项),并且不需要严格的事务隔离,则可能适合使用非严格读/写缓存。如果在JTA环境中使用缓存,则必须指定hibernate.transaction.manager_lookup_class。在其他环境中,您应确保当调用Session.close()Session.disconnect()时完成事务。

19.2.5. 策略:事务性

事务性缓存策略提供对完全事务性缓存提供程序(例如JBoss TreeCache)的支持。这种高速缓存只能在JTA环境中使用,请务必指定hibernate.transaction.manager_lookup_class

换句话说:

  • 只读:适用于需要频繁读取但从不更新的数据(例如国家等参考数据)。它很简单。它拥有所有策略中最好的性能(显然)。

  • 读/写:如果您的数据需要更新,则使用此策略更佳。但是它不提供SERIALIZABLE隔离级别,可能会出现phantom reads(您可能会在事务结束时看到一些起始时不存在的内容)。它比只读策略有更多的开销。

  • 非严格读/写:或者,如果两个独立的事务线程不太可能更新同一个对象,则可以使用非严格读写策略。它比读/写策略有更少的开销。这对于很少更新的数据很有用。

  • 事务性:如果需要完全事务性缓存。仅适用于JTA环境。

因此,选择正确的策略取决于数据是否正在更新,更新的频率以及所需的隔离级别。如果您不知道如何回答有关要放入缓存的数据的这些问题,可以向DBA寻求支持。


@Pascal,对于可靠性标准,“事务性”是最好的选择,但性能不佳,对吧?你能详细说明一下JTA环境是什么吗?它是EJB吗? - cometta
1
不,你可以在EJB容器外使用JTA。 - Adeel Ansari
使用事务,需要有支持它的缓存提供程序吗?Ehcache 可以使用吗?我正在使用 Ehcache + Spring HibernateTemplate + JPA 实体,这是否被视为 JTA 环境? - cometta
1
@cometta 我不会说性能很差,而是你使用它时会得到最大的开销。 - Pascal Thivent
@cometta 不,EHCache不支持事务策略,正如http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache-compat-matrix中所述。 - Pascal Thivent

12

READ_ONLY: 仅用于从不更改的实体(如果尝试更新此类实体将引发异常)。它非常简单且性能良好,非常适合一些静态参考数据,这些数据不会更改。

NONSTRICT_READ_WRITE: 缓存在修改受影响的数据的事务提交后更新。因此,无法保证强一致性,并且在缓存中可能获取到过时的数据。这种策略适用于可以容忍最终一致性的用例。

READ_WRITE: 此策略通过使用“软”锁来实现强一致性:当缓存实体被更新时,会为该实体在缓存中存储一个软锁,该锁在事务提交后被释放。所有访问软锁定条目的并发事务都将直接从数据库获取相应的数据。

TRANSACTIONAL: 缓存更改是在分布式XA事务中完成的。缓存实体的更改在同一XA事务中在数据库和缓存中提交或回滚。


4

0
  1. 事务性 - 在读多写少的数据中使用此策略,以防止并发事务中出现陈旧数据,在更新的罕见情况下。

  2. 读写 - 再次在读多写少的数据中使用此策略,在更新的罕见情况下,防止并发事务中出现陈旧数据。

  3. 非严格读写 - 此策略不保证缓存和数据库之间的一致性。如果数据几乎不会更改,并且很少出现陈旧数据的可能性不是关键问题,请使用此策略。

  4. 只读 - 适用于永远不会更改的数据的并发策略。仅用于参考数据。

希望这能解决您的疑问!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接