【问题标题】:Does Spring @Transactional use any Hibernate cache?Spring @Transactional 是否使用任何 Hibernate 缓存?
【发布时间】:2015-01-10 18:05:18
【问题描述】:
@Transactional
public MyEntity getEntity(long id) {
    return dao.findOne(id);

    //or select and update as well
}

每次我调用事务方法时:我会从休眠中获取任何缓存的实体(第一次除外)吗?还是我总是会从数据库中获取新实体?

这很重要,因为我将有两个独立的应用程序共享同一个数据库,并且我想确保休眠不会返回任何缓存的实体,而另一个应用程序可能已经在后台更新了数据库中的同一实体。

【问题讨论】:

    标签: java spring hibernate transactions spring-transactions


    【解决方案1】:

    如果这是您的服务层的事务边界,那么 Hibernate 将创建一个新会话,这意味着 first level cache 中没有任何内容。如果您尝试在同一个服务方法中调用findOne 方法两次,第二次调用将从缓存中获取实体。

    连续的服务方法调用(例如 getEntity)总是以一个新的 Hibernate Session 结束,因此从数据库中加载一个新的实体。

    如果您使用二级缓存并为此实体激活它,那么 Hibernate 将始终首先命中缓存并在缓存未命中时回退到数据库加载。

    为防止数据完整性异常,请考虑使用optimistic locking

    【讨论】:

      【解决方案2】:

      简短的回答是肯定的。
      长答案是:@Transactional 所做的只是为您提供休眠会话,并开始/提交事务(如果配置为这样做)。 它不关心会话是否启用了缓存。缓存由会话在内部完成。
      因此,您只需要了解休眠缓存:
      默认启用一级缓存(每个会话),您无法禁用它,
      二级缓存(每个 SessionFactory)默认禁用,请参阅 here 如何启用 Ehcache(只有 @Cache 注释的实体最终在 2 级缓存中)。
      @Transactional 是否会打开新会话,或者会重用现有会话,是可配置的,这取决于 CurrentSessionContext 实现。您可以插入自己的实现。

      【讨论】:

        猜你喜欢
        • 2014-06-04
        • 1970-01-01
        • 1970-01-01
        • 2019-07-10
        • 2012-10-15
        • 1970-01-01
        • 2018-11-23
        • 2013-06-23
        • 2019-07-31
        相关资源
        最近更新 更多