envers
当然,对于每个请求,我们都必须知道版本号–这就是为什么必须将其存储在全局缓存中(但根据我们的一致性要求,它也可以异步分布在整个集群中)。 但是,数据本身可以存储在本地缓存中。 因此,如果我们的系统是只读的,那么每个请求唯一要做的“昂贵”操作就是检索我们感兴趣的实体的版本号。这通常是非常简单的信息,可以完全保留在-记忆。
根据数据类型和使用模式,您可以缓存单个实体(例如,对于Person
实体,缓存键可以是person-9128-123
是id,版本号123)或全部(例如,对于一个Countries
实体,缓存密钥可以是countries-8
,版本号是8。 此外,在全局缓存中,您可以按ID或按实体保存最新的版本号; 意味着当版本更改时,您会使特定实体或所有实体无效。
编写了大部分Envers之后 ,我自然就可以将实体修订号用作缓存版本 。 随后的Envers修订版是单调递增的数字,对于每个事务,您都会获得下一个。 因此,每当缓存的实体发生更改时,您都必须使用最新的修订版号填充全局缓存。
Envers提供了几种获取修订号的方法。 在事务期间,您可以调用AuditReader .getCurrentRevision()
方法,该方法将为您提供修订元数据,包括修订号。 如果您想要更细粒度的控制,则可以实现自己的侦听器( EntityTrackingRevisionListener
),请参阅docs ,并在实体更改时得到通知,并在那里更新全局缓存。 您还可以注册交易完成后的回调,并在事务边界之外更新缓存。 或者,如果您知道实体ID,则可以使用AuditReader.getRevisions
或AuditQueryCreator
查找最大修订版本号。
由于您可以在事务处理过程中获取当前的修订版本号,因此,如果使用事务性缓存(例如Infinispan) ,甚至可以原子地更新全局缓存中的版本/修订版。
当然,除了审计之外,所有这些仍然是Envers的主要目的:)
参考: Adam Warski博客的Blog中来自JCG合作伙伴 Adam Warski的分代缓存和Envers 。
翻译自: https://www.javacodegeeks.com/2012/07/generational-caching-and-envers.html
envers