数据一致性 - 969251639/study GitHub Wiki

互联网企业中,经常会有数据一致性问题,其根本的原因无非就是DB与Cache是两个独立的运行组件(有可能有网络开销,两者非本地)而不能保证原子操作引起的事务问题,网上有很多方案,下面说下自己项目中搭建的方案

为了解决原子操作,可以考虑将一个操作下放到DB中,什么意思呢?就是建立一张表,记录一个操作,该表的操作与本地事务绑在一起,这样,这张表的操作要么与本地事务操作一起成功,一起失败,可以拦截Transactional注解坐代码解耦,表设计如下
id:主键
service:业务
keys:引起变化的数据的key,可以多个,用逗号隔开
spring_bean: spring bean名称
method: 加载数据的方法
params: 方法参数

执行流程如下:

  1. 每次需要同步数据时,先将要同步的数据插入到上面设计的表
  2. 启动一个线程,然后休眠
  3. 如果上面的操作提交事务,那么唤醒线程进行数据一致性的同步操作
  4. 一批一批的读取上面的表,如果读取到的为空,那么继续休眠
  5. 将读取到的表数据根据spring_bean找到该spring的service对象,然后再根据上面的method,params,进行数据回调,读取最新数据,写到Cache中
  6. 将数据回放完后根据id删除上面的数据即可

当然,上面逻辑也可以写到mq中,到mq中去同步这些操作,但又会依赖mq中间件,且还需要保证消息不丢不重复等一系列麻烦的东西,故采取上面的一种轻量级方案,缺点是需要在数据库中新增一张数据同步表

注:以上的一种方案是一种接近强一致的方案,若允许Cache暂时miss,那么删除key后在加载会更简单