我在项目中使用了mongo集群存储,并使用了通用的读写分离配置
mongodb://****:37017/******?readPreference=secondaryPreferred
然后在业务代码中有这么一段逻辑,先更新User表中的某几个字段,然后query出该条数据,更新到缓存中。
// 更新了info数据的某几个字段
await _infoRepository.UpdateUserLevelAsync(uid, code, level, updateBy);
// 更新缓存
var info=await _infoRepository.FindUserAsync(uid, code)
var cacheEntity = _mapper.Map<UserEntity>();
测试时,发现偶然会存在 数据与缓存不一致的情况。经排查确认因为读写分离的关系,从mongo从库中query的数据可能同步不及时,而取到旧数据造成。
于是修正 _infoRepository.FindUserAsync(uid, code)
方法,增加了一个强制从主库query的参数。mongo 单次查询定义读选项代码如下:
var list = readPrimaryPreferred ? await _collection.WithReadPreference(ReadPreference.PrimaryPreferred)
.FindSync(query).ToListAsync()
: await FindAsync(query);
问题解决。
总结:这个问题并不难,但很容易在写代码逻辑的时候忽略,因为通常主从查询并不属于具体的业务逻辑块,今后类似情况当特别留心注意。