介绍
当信息分散在各种数据提供者之间时,记录系统是权威的数据源。 当我们引入缓存解决方案时 ,我们会自动复制数据。 为避免不一致的读取和数据完整性问题,同步数据库和缓存(无论何时对系统进行更改)都是非常重要的。
有多种方法可以使缓存和基础数据库保持同步,本文将介绍一些最常见的缓存同步策略。
暂存
应用程序代码可以手动管理数据库和缓存信息。 应用程序逻辑在命中数据库之前检查缓存,并在任何数据库修改后更新缓存。
混合缓存管理和应用程序并不是很吸引人,特别是如果我们必须在每种数据检索方法中重复这些步骤时。 利用面向方面的缓存拦截器可以减轻缓存泄漏到应用程序代码中的风险,但这并不能使我们确保数据库和缓存都正确同步。
通读
除了管理数据库和缓存之外,我们还可以简单地将数据库同步委托给缓存提供程序。 因此,所有数据交互都是通过缓存抽象层完成的。
在获取缓存条目后,缓存会验证缓存元素的可用性并代表我们加载基础资源。 该应用程序将高速缓存用作记录系统,并且高速缓存能够按需自动填充。
直写
类似于通读数据获取策略,每次更改缓存条目时,缓存都可以更新基础数据库。
尽管数据库和缓存是同步更新的,但是我们仍然可以根据我们当前的业务需求选择事务边界。
- 如果必须具有高度的一致性,并且缓存提供程序提供了XAResource,我们可以在同一全局事务中注册缓存和数据库。 因此,数据库和高速缓存是在单个原子工作单元中更新的
- 如果一致性可能变弱,我们可以按顺序更新缓存和数据库,而无需使用全局事务。 通常,首先更改缓存,如果数据库更新失败,则缓存可以使用补偿操作来回滚当前事务更改
后写
如果没有强一致性要求,我们可以简单地使高速缓存更改入队,并定期将其刷新到数据库。
Java Persistence EntityManager (第一级缓存)采用此策略,所有实体状态转换都将在当前运行的事务结束时(或发出查询时)刷新。
尽管它破坏了事务保证,但是后写缓存策略的性能要优于直写策略,因为可以分批更新数据库并且还可以减少DML事务的数量。
翻译自: https://www.javacodegeeks.com/2015/04/a-beginners-guide-to-cache-synchronization-strategies.html