多次请求与修改的并发控制:多实例下分布式锁和乐观锁的应用
2023-12-16 12:29:38
前提:
在正式环境中,由于存在多个实例,同一笔订单可能会被多次请求到我的数据汇总接口。为了避免重复处理订单,我采用了分布式锁来进行拦截。
另外,考虑到在 1 秒内可能会有多笔不同订单同时进行数据修改,如果直接修改可能会出现数据覆盖的情况。例如,订单 A 的金额是 1 元,订单 B 的金额是 2 元,如果不采取任何措施直接修改,汇总表中的金额可能会出现 1 元、2 元或 3 元的情况,而不是正确的 4 元。为了解决这个问题,我们采用了乐观锁来限制并发修改,以确保数据的准确性。
以下是处理代码
//分布式锁
String lockKey = "profit_export_log"+orderNo;
// true-加锁成功
boolean isSuccess = RedisUtils.getRedisStringTemplate().opsForValue().setIfAbsent(lockKey,orderNo, Constant.TEN, TimeUnit.MINUTES);
if (!isSuccess) {
log.info("汇总分润-{}. id:{}. lockKey:{}. 获取分布式锁失败!", "汇总分润" ,orderNo, lockKey);
return;
}
//乐观锁
MiddleCollectVo collectVo = MiddleCollectMapper.queryOneValue(exportLogMiddleVo);
MiddleCollectDto collectDto = BeanMapperUtils.map(exportLogMiddleVo, MiddleCollectDto.class);
updateNoRefundCgcProfitExportLogCollect(exportLogMiddleVo, collectVo, collectDto);
int newVersion = collectVo.getVersion() + 1;
MiddleCollect value = BeanMapperUtils.map(collectDto,MiddleCollect.class);
LambdaUpdateWrapper<MiddleCollect> wrapper= Wrappers.lambdaUpdate(MiddleCollect.class);
wrapper.eq(MiddleCollect::getId, collectVo.getId());
wrapper.eq(MiddleCollect::getVersion, collectVo.getVersion());
value.setVersion(newVersion);
boolean judge = this.update(value, wrapper);
if(!judge) {
updateAgain(exportLogMiddleVo);
}
文章来源:https://blog.csdn.net/weixin_47287824/article/details/135030234
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!