保证缓存一致性
无论是对象缓存和关联缓存那种全自动的一致性,还是计算缓存那种需要用户辅助的一致性,Jimmer的缓存一致性都是由触发器驱动的。
Jimmer的触发器分为BinLog触发器和Transaction触发器。
针对不同的情况,Jimmer采用不同的策略来保证缓存一致性,即,保证缓存清理操作必然成功。
BinLog触发器的一致性(推荐)
当trigger-type
为BINLOG_ONLY
或BOTH
时,Jimmer使用BinLog触发器删除失效缓存。
在这种情况下,开发人员响应消息队列的通知,简单处理后调用Jimmer的BinLog
API (这段用户代码很简单,其复杂度可以忽略不计)。用户调用BinLog
API会发起所有触发器回调,包括缓存删除。
以Kafka为例,只要保证调用BinLog
API成功后才提交消费进度,则可以保证缓存清理最终成功。
Transaction触发器的一致性
当trigger-type
为TRANSACTION_ONLY
时,Jimmer会被迫使用Transaction触发器删除失效缓存。
对于Transaction触发器而言:
-
只有用户在当前App内调用Jimmer API导致的修改才做才会发起触发器回调。
-
所有触发器回调都在事务提交前完成。
假如采用直接删除缓存的简单实现,只要缓存删除发生异常,就会导致事务被回滚。很明显,这种实现并不合理。
因此,当trigger-type
为TRANSACTION_ONLY
时,用户认知中的缓存删除操作都会被延迟执行。缓存删除操作先不执行,而是被存入JIMMER_TRANS_CACHE_OPERATOR
表。
Jimmer会自动创建``JIMMER_TRANS_CACHE_OPERATOR`表。
然而,默认的org.babyfish.jimmer.sql.dialect.DefaultDialect
不支持此操作,会抛出异常。
因此,如果需要用Transaction触发器驱动缓存一致性,就不要使用默认的DefaultDialect
,要明确指定数据库方言。
JIMMER_TRANS_CACHE_OPERATOR
表的修改和业务表的修改属于同一个数据库本地事务,二者要么都成功,要么都失败。
事务提交成功后,Jimmer会马上执行一次Flush
操作。
所谓Flush
操作,就是从JIMMER_TRANS_CACHE_OPERATOR
表中获取尚未执行的用户认知中的缓存删除操作,执行真正的缓存删除操作,如果成功,删除相关记录。
对于事务提交后立即执行的Flush
操作而言:
-
如果成功自然最好,这时拥有良好的实时性。大部分情况下也应该如此。
-
即使没有成功也不要紧。因为Jimmer会周期性执行
Flush
操作保证相关缓存操作最终会成功。Flush
操作的间隔受全局SpringBoot配置项jimmer.transaction-cache-operator-fixed-delay
控制,该配置以毫秒为单位,默认5000