- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
简而言之,当在方法上调用 @CacheEvict 时,如果未找到条目的键,Gemfire 将抛出 EntryNotFoundException。
现在详细说明,
我有课
class Person {
String mobile;
int dept;
String name;
}
我有两个缓存区域定义为 personRegion 和 personByDeptRegion,服务如下
@Service
class PersonServiceImpl {
@Cacheable(value = "personRegion")
public Person findByMobile(String mobile) {
return personRepository.findByMobile(mobile);
}
@Cacheable(value = "personByDeptRegion")
public List<Person> findByDept(int deptCode) {
return personRepository.findByDept(deptCode);
}
@Caching(
evict = { @CacheEvict(value = "personByDeptRegion", key="#p0.dept"},
put = { @CachePut(value = "personRegion",key = "#p0.mobile")}
)
public Person updatePerson(Person p1) {
return personRepository.save(p1);
}
}
当调用 updatePerson 时,如果 personByDeptRegion 中没有条目,则会抛出键 1 (或任何部门代码)的 EntryNotFoundException 异常。这个方法很有可能会在 @Cacheable 方法被调用之前被调用,并且希望避免这个异常。当给定区域的 key 不存在时,我们是否可以调整 Gemfire 的行为以优雅地返回?另外,我也很想知道是否有使用 Gemfire 作为缓存更好地实现上述场景。
Spring 数据 Gemfire:1.7.4
Gemfire 版本:v8.2.1
注意:上面的代码仅供引用,我在实际项目中有多个服务存在相同的问题。
最佳答案
首先,我赞扬您在应用程序上使用 Spring 的缓存注释 @Service
成分。开发人员经常在他们的存储库中启用缓存,我认为这是不好的形式,特别是如果在存储库交互之前或之后涉及复杂的业务规则(甚至额外的 IO;例如从服务组件调用 Web 服务) ,特别是在缓存行为不应受到影响(或确定)的情况下。
我还认为您通过遵循 personRegion
来缓存 UC(在数据存储更新时更新一个缓存 ( personByDeptRegion
),同时使另一个缓存 ( CachePut
) 无效)与 CacheEvict
对我来说似乎很合理。不过,我想指出 @Caching
的看似预期用途注解是组合多个相同类型的缓存注解(例如多个 @CacheEvict
或多个 @CachePut
),如核心 Spring 框架 Reference Guide 中所述。 。尽管如此,没有什么可以阻止您的预期用途。
我创建了一个类似的测试类here ,仿照上面的示例来验证问题。确实是jonDoeUpdateSuccessful测试用例失败(使用 GemFire EntryNotFoundException
,如下所示),因为 Department
中没有人与 janeDoeUpdateSuccessful 不同,“R&D”在更新之前之前已缓存在“DepartmentPeople
”GemFire 区域中。测试用例,这会导致在更新之前填充缓存(即使该条目没有值,这也没有影响)。
com.gemstone.gemfire.cache.EntryNotFoundException: RESEARCH_DEVELOPMENT
at com.gemstone.gemfire.internal.cache.AbstractRegionMap.destroy(AbstractRegionMap.java:1435)
NOTE: My test uses GemFire as both a "cache provider" and a System of Record (SOR).
问题确实在于 SDG 使用 Region.destroy(key)在 GemfireCache.evict(key)实现而不是,也许更合适,Region.remove(key) .
GemfireCache.evict(key)
已实现 Region.destroy(key)
自成立以来。然而,Region.remove(key)
直到 GemFire v5.0 才引入。尽管如此,我还是看不出 Region.destroy(key)
之间有明显的区别。和Region.remove(key)
除了 EntryNotFoundException
由 Region.destroy(key)
抛出。本质上,它们都会破坏本地条目(键和值),并将操作分发到集群中的其他缓存(假设使用了非 LOCAL
Scope)。
所以,我已经提交了SGF-539将 SDG 更改为调用 Region.remove(key)
在GemfireCache.evict(key)
而不是Region.destroy(key)
.
至于解决方法,基本上您只能做两件事:
@CacheEvict
的使用注释,和/或...condition
上@CacheEvict
.不幸的是condition
无法使用类类型来指定,类似于 Spring Condition (除了 SpEL),但此接口(interface)用于其他目的,并且 @CacheEvict
, condition
属性不接受类类型。
目前,我还没有一个很好的例子来说明它是如何工作的,所以我将继续前进 SGF-539 .
您可以关注此票证以了解更多详细信息和进度。
抱歉给您带来不便。
-约翰
关于java - @CacheEvict 的 Gemfire EntryNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39830488/
我正在将 GemFire 集群从 8.2.7(使用 Spring Data GemFire 1.6.0.RELEASE)迁移到 Pivotal GemFire 9.3.0(SDG 2.0.7.RELE
我正在尝试按日期查询我的 gemfire 区域。任何人都可以帮助解决如何格式化 to_date 以便对我的 gemfire 区域进行日期查询。 我有一个格式为 'MM/dd/yyyy' 的日期,然后我
我想在 Spring Boot 应用程序中创建一个 Gemfire 区域。按照这个 sample ,它在不添加数据库支持的情况下运行良好。如果我添加数据库,它会显示错误,如“创建名称为‘dataSou
我正在尝试使用 Spring Data GemFire 和 Spring Boot 连接到现有的 GemFire 定位器。 以下是我的缓存配置 当我尝试运行此代码时
我正在尝试使用 Spring Data GemFire 和 Spring Boot 连接到现有的 GemFire 定位器。 以下是我的缓存配置 当我尝试运行此代码时
我的团队使用 Geode 作为临时分析引擎。我们在 Geode 中存储了大量原始数据对象(每个 200MB+),但这些对象永远不会直接返回给客户端。相反,我们严重依赖自定义函数执行来在 Geode 内
我一直在研究“内存数据网格”,并看到了“gemfire”一词。我很困惑。似乎 gemfire 是一个术语,指的是像数据库一样存储和操作数据但在计算机内存中的技术,不是吗? gemfire到底是什么?
我正在为一个 Java 应用程序编写设计文档,其中两个冗余进程从消息队列中读取项目,我们希望它们都使用相同的 key 将项目存储到 gemfire 存储中,目的是许多运行连续查询的应用程序会处理这些项
我正在尝试在 springXD 中设置流。 gemfire 安装在 10.99.40.60 机器上,springXD 安装在我的本地 VM 上。 xd:>stream create -
我有一个客户端/服务器拓扑场景。 在本地运行由一个定位器和两台服务器组成的简单集群,不同的 JVM 进程,服务器在启动时没有使用以下配置创建区域: ${gemfire.server.na
我正在尝试使用 gfsh 启动定位器,但我不断发现找不到主类。 我正在运行这个:gfsh start locator --name=locator1 此后我收到以下错误: Error: Could n
我正在与 GemFire 合作开展一个项目。为了将数据从数据库导入到 GemFire,我做了一个连接到数据库和 GemFire 的 java 程序,然后我从数据库中选择数据并放入它位于 GemFire
我试图在一个 JVM 中创建一个本地缓存和一个客户端缓存,但是我收到下面所述的错误,我认为这是由于缓存是单例而发生的,并且每个 JVM 只能创建一个。 有没有人知道一个好的解决方法? 错误: Erro
我正在使用 gemfire,目前有一个客户端和一个服务器。现在,服务器动态地在一个区域中创建一些子区域,并在其中放置一些对象。我正在尝试使用客户端检索对象,但看不到对象或子区域。如何同步区域?我还能做
我有一个嵌入到具有本地 Gemfire 缓存的 Web 服务中的 JAR。我试图解决的问题是这些数据的过期。 我创建了一个自定义过期计时器,它将设置每个条目的过期时间(以秒为单位),并绑定(bind)
在此gemfire tutorial 我无法解释这个通用声明: people = cache.createRegionFactory(REPLICATE) .addCacheListene
我使用 gemfire 作为我的缓存。缓存堆大小远高于 100GB。我发现当我们从客户端将数据放入gemfire缓存中时,它会序列化数据并发送给服务器,并且在服务器上数据以序列化形式存储。问题: 当我
我们使用 Pivotal Gemfire 作为数据缓存。最近,我们从 gemfire 8.2.1 迁移到 9.5.1,具有完全相同的区域、数据和索引。但是在特定的一个区域上创建索引花费了太多时间,该区
当我在 gfsh 控制台中运行 SELECT 查询时,它按预期工作: query --query="SELECT * FROM /channelProfiles_composite_asrd WHER
我已经为我的用例搜索了解决方案,但没有找到正确的解决方案,因此期待一些好的想法可以进一步探索。 我有两个 gemfire(版本 8.2)集群(私有(private)和公共(public)),每个集群都
我是一名优秀的程序员,十分优秀!