作者:Eddy  历史版本:1  最后编辑:龚清  更新时间:2024-05-27 11:07

缓存如何与事务保持一致性

什么是缓存与事务保持一致性

  在业务系统中会出现这样的场景,模块A与模块B的业务存在关联。场景C需要同时处理模块A和模块B的数据,先保存模块A的数据,业务流转到模块B,模块B需要查询模块A的数据。应用内部有缓存机制,会将模块A的数据加载到缓存,如果模块B的业务出现异常,则本次事务内的数据(模块A、模块B)都需要回滚,但此时模块A的数据已经被加载到缓存中,需要将该缓存清除才能保证事务与缓存数据一致。

设计思路

事务内产生的数据不应该被缓存加载

  1. 模块A数据写入时,通过线程变量将数据标识保存起来。
  2. 模块B需要模块A的数据时,判断是否在线程变量中存在所需模块A的数据标识,如果存在则不查询缓存,直接查询数据库,否则从缓存中加载。
  3. 最后不要忘记清除线程变量,避免内存泄露。

基于spring如何获取事务名称

org.springframework.transaction.support.TransactionSynchronizationManager.getCurrentTransactionName();

事务内产生的数据被缓存加载后,如果事务失败需要清除

会出现被其他线程读取到的风险,存在线程不安全,不推荐使用该方案

  1. 模块A数据写入时,发布一个事务监听事件,事务失败后执行。
  2. 模块B需要模块A的数据时,从缓存中加载。
  3. 事务失败,删除被加载到缓存的脏数据。

基于spring事件监听注解org.springframework.transaction.event.TransactionalEventListener

    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
   public void handle(TransactionalMessageEvent event) {
       //TODO 清除缓存数据
   }