Spring @Transactional使用任何Hibernate缓存吗?

5
@Transactional
public MyEntity getEntity(long id) {
    return dao.findOne(id);

    //or select and update as well
}

每次调用事务方法,除了第一次,我会不会从Hibernate中获取任何缓存实体?还是我总是会获得从数据库中获取的新鲜实体?

这很重要,因为我将有两个独立的应用程序共享同一个数据库,并且我希望确保当另一个应用程序在后台更新相同实体时,Hibernate不返回任何缓存实体。

2个回答

10
如果这是您的服务层事务边界,Hibernate将创建一个新的Session,这意味着一级缓存中没有任何内容。如果您尝试在同一服务方法内两次调用findOne方法,则第二次调用将从缓存中获取实体。
连续的服务方法调用(例如getEntity)总是会得到一个新的Hibernate Session,因此会从数据库加载一个新的实体。
如果您使用第二级缓存并激活它来保存这个实体,那么Hibernate将始终首先命中缓存,然后在缓存未命中时回退到数据库加载。
为了防止数据完整性异常,请考虑使用乐观锁定

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

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