Spring @Transactional 使用任何 Hibernate 缓存吗?
Does Spring @Transactional use any Hibernate cache?
@Transactional
public MyEntity getEntity(long id) {
return dao.findOne(id);
//or select and update as well
}
每次我调用事务方法:我是否会从休眠中获取任何缓存的实体(第一次除外)?或者我总是会从数据库中获取新的实体吗?
这很重要,因为我将有两个独立的应用程序共享同一个数据库,我想确保休眠不会 return 任何缓存的实体,而另一个应用程序可能已经更新了同一个实体数据库在后台。
如果这是您的服务层的事务边界,那么 Hibernate 将创建一个新会话,这意味着 first level cache 中没有任何内容。如果您尝试在同一个服务方法中两次调用 findOne
方法,第二次调用将从缓存中获取实体。
连续的服务方法调用(例如 getEntity)总是以一个新的 Hibernate 会话结束,因此从数据库中加载了一个新的实体。
如果您使用二级缓存并为此实体激活它,那么 Hibernate 将始终先访问缓存,然后在缓存未命中时回退到数据库加载。
为防止数据完整性异常,请考虑使用 optimistic locking。
简短的回答是肯定的。
长答案是:@Transactional 所做的就是为您提供一个休眠会话,并且 begin/commit 一个事务,如果配置为这样做的话。
它不关心会话是否启用了缓存。缓存由会话在内部完成。
所以你只需要了解休眠缓存:
一级缓存(每个会话)默认启用,你不能禁用它,
二级缓存(每个 SessionFactory)在默认情况下是禁用的,参见here如何启用 Ehcache(只有 @Cache 注释的实体最终在二级缓存中)。
@Transactional 是打开新会话还是重用现有会话是可配置的,它取决于 CurrentSessionContext 实现。您可以插入自己的实现。
@Transactional
public MyEntity getEntity(long id) {
return dao.findOne(id);
//or select and update as well
}
每次我调用事务方法:我是否会从休眠中获取任何缓存的实体(第一次除外)?或者我总是会从数据库中获取新的实体吗?
这很重要,因为我将有两个独立的应用程序共享同一个数据库,我想确保休眠不会 return 任何缓存的实体,而另一个应用程序可能已经更新了同一个实体数据库在后台。
如果这是您的服务层的事务边界,那么 Hibernate 将创建一个新会话,这意味着 first level cache 中没有任何内容。如果您尝试在同一个服务方法中两次调用 findOne
方法,第二次调用将从缓存中获取实体。
连续的服务方法调用(例如 getEntity)总是以一个新的 Hibernate 会话结束,因此从数据库中加载了一个新的实体。
如果您使用二级缓存并为此实体激活它,那么 Hibernate 将始终先访问缓存,然后在缓存未命中时回退到数据库加载。
为防止数据完整性异常,请考虑使用 optimistic locking。
简短的回答是肯定的。
长答案是:@Transactional 所做的就是为您提供一个休眠会话,并且 begin/commit 一个事务,如果配置为这样做的话。
它不关心会话是否启用了缓存。缓存由会话在内部完成。
所以你只需要了解休眠缓存:
一级缓存(每个会话)默认启用,你不能禁用它,
二级缓存(每个 SessionFactory)在默认情况下是禁用的,参见here如何启用 Ehcache(只有 @Cache 注释的实体最终在二级缓存中)。
@Transactional 是打开新会话还是重用现有会话是可配置的,它取决于 CurrentSessionContext 实现。您可以插入自己的实现。