作者:Eddy 历史版本:1 最后编辑:龚清 更新时间:2024-05-27 11:07
缓存如何与事务保持一致性
什么是缓存与事务保持一致性
在业务系统中会出现这样的场景,模块A与模块B的业务存在关联。场景C需要同时处理模块A和模块B的数据,先保存模块A的数据,业务流转到模块B,模块B需要查询模块A的数据。应用内部有缓存机制,会将模块A的数据加载到缓存,如果模块B的业务出现异常,则本次事务内的数据(模块A、模块B)都需要回滚,但此时模块A的数据已经被加载到缓存中,需要将该缓存清除才能保证事务与缓存数据一致。
设计思路
事务内产生的数据不应该被缓存加载
- 模块A数据写入时,通过线程变量将数据标识保存起来。
- 模块B需要模块A的数据时,判断是否在线程变量中存在所需模块A的数据标识,如果存在则不查询缓存,直接查询数据库,否则从缓存中加载。
- 最后不要忘记清除线程变量,避免内存泄露。
基于spring如何获取事务名称
org.springframework.transaction.support.TransactionSynchronizationManager.getCurrentTransactionName();
事务内产生的数据被缓存加载后,如果事务失败需要清除
会出现被其他线程读取到的风险,存在
线程不安全
,不推荐使用该方案
- 模块A数据写入时,发布一个事务监听事件,事务失败后执行。
- 模块B需要模块A的数据时,从缓存中加载。
- 事务失败,删除被加载到缓存的脏数据。
基于spring事件监听注解org.springframework.transaction.event.TransactionalEventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK) public void handle(TransactionalMessageEvent event) { //TODO 清除缓存数据 }