Hibernate缓存策略

如何确定要使用哪个CacheConcurrencyStrategy

  • NonstrictReadWriteCache
  • ReadOnlyCache
  • ReadWriteCache
  • TransactionalCache

我阅读了https://www.hibernate.org/hib_docs/v3/api/org/hibernate/cache/CacheConcurrencyStrategy.html ,但没有详细解释。

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隔离级别,可能会发生幻像读取 (您可能会在事务结束时看到某些事情在开始时不存在)。 它具有比只读更多的开销。

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

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

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

阅读API文档是件好事,但你也应该阅读文档(它很棒), 二级缓存 – 策略 。

READ_ONLY:仅用于从不更改的实体(如果尝试更新此类实体,则抛出exception)。 它非常简单,高效。 非常适合一些不会改变的静态参考数据。

NONSTRICT_READ_WRITE:在已提交更改受影响数据的事务之后更新缓存。 因此,不能保证强一致性,并且存在可以从高速缓存获得陈旧数据的小时间窗口。 这种策略适用于能够容忍最终一致性的用例。

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

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

  1. 事务性 – 在极少数更新的情况下,将此策略用于读取主要数据,这对于防止并发事务中的过时数据至关重要。

  2. 读写 – 再次将此策略用于读取主要数据,在这种情况下,在极少数情况下更新时,防止并发事务中的陈旧数据至关重要。

  3. Nonstrict-read-write – 此策略不保证缓存和数据库之间的一致性。 如果数据几乎没有变化,并且过时数据的可能性很小,则不要使用此策略。

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

希望这能清除你的怀疑!