我们有一个应用程序使用 Hibernate 的二级缓存来避免数据库命中。
我想知道当外部进程(例如 MySQL 管理员)直接连接到修改数据库(更新/插入/删除)时,是否有一些简单的方法可以使 Java 应用程序的 Hibernate 二级缓存无效。
我们使用EHCache作为我们的二级缓存实现。
我们混合使用@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 和@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE),并且我们没有使用每个实体上的时间戳启用乐观并发控制。
SessionFactory 包含管理二级缓存的方法: -管理缓存
sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class); //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
但是因为我们使用@Cache 注释单个实体类,所以我们没有中心位置可以“可靠地”(例如,没有手动步骤)将其添加到列表中。
// Easy to forget to update this to properly evict the class
public static final Class[] cachedEntityClasses = {Cat.class, Dog.class, Monkey.class}
public void clear2ndLevelCache() {
SessionFactory sessionFactory = ... //Retrieve SessionFactory
for (Class entityClass : cachedEntityClasses) {
sessionFactory.evict(entityClass);
}
}
Hibernate 的二级缓存没有真正的方法知道数据库中的实体已更改,除非它查询该实体(这是缓存保护您免受的)。因此,也许作为一种解决方案,我们可以简单地调用一些方法来强制二级缓存驱逐所有内容(同样由于缺乏锁定和并发控制,您可能会在进行中的事务中“读取”或更新陈旧数据)。