當然,對于每個請求,我們都必須知道版本號,這就是為什么必須將其存儲在全局緩存中(但根據我們的一致性要求,它也可以異步地分布在整個集群中)。 但是,數據本身可以存儲在本地緩存中。 因此,如果我們的系統是只讀的,那么每個請求唯一要做的“昂貴”操作就是檢索我們感興趣的實體的版本號。這通常是非常簡單的信息,可以完全保留在-記憶。
根據數據類型和使用模式,您可以緩存單個實體(例如,對于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