一、背景描述
1、今天接到一个老需求改造:如果一个用户多次提交不同的订单,则将该用户(依据手机号)设置成一个专业投诉人或取消设置。
2、系统存储数据时采用的是同一个人不同的单据则存放成不同的实体。
3、存在租户的概念,本次更新的范围也是租户下所有该用户(依据手机号)
二、具体分析
1、因为系统使用的是微服务实现,订单信息在另外一个服务上,新增一个根据手机号进行批量更新的接口代价大且用途有限。
2、因为系统已经运行很久有很多历史数据,所以该功能除了要完成实现还要考了性能问题
3、与前端交互时,前端也是传回了当前人信息记录的id,所有涉及到要查询数据库拿回当前人信息的问题
4、为了兼顾性能只能先更新当前单据的,然后再异步设置相关的其他单据的人。
三、具体实现
1、为了达到多个事件可以共用,所有设置通过入参来区分不同的场景
a、bizType是业务类型,区分不同的场景
b、bizObject是主要的传递的对象
c、bizParam是必要的附加属性
d、必要的静态
2、调用端和消费端代码
Map<String, Object> bizParam = new HashMap<>(16); bizParam.put("context", context); bizParam.put("userFeature", userFeature); bizParam.put("roleAccuserBuyer", ROLE_ACCUSER_BUYER); applicationContext.publishEvent(
BusinessEvent.generate(this,
EventConstants.BATCH_UPDATE_FEATURE, mediateEntityDTO, bizParam));
return ActionResult.getSuccessResult("操作成功");
@Async @EventListener @Override public void batchUpdateFeature(BusinessEvent event) { if(!EventConstants.BATCH_UPDATE_FEATURE.equals(event.getBizType())) { return; } logger.info("batchUpdateFeature begin. event is : {}", JSONObject.toJSONString(event)); MediateEntityDTO mediateEntityDTO = (MediateEntityDTO) event.getBizObject(); if(StringUtils.isEmpty(mediateEntityDTO.getMobile())) { logger.warn("update other relation entity fail without mobile!"); return ; } //获取参数 Map<String, Object> bizParam = event.getBizParam(); Context context = (Context) bizParam.get("context"); List<String> roleAccuserBuyer = (List<String>) bizParam.get("roleAccuserBuyer"); String userFeature = (String) bizParam.get("userFeature");
}
a、监听一定要设置成异步,否则就没意义了 ,@Async注解的生效需要在application注解上引入@EnableAsync,启动异步
b、之前之后要打印日志,这样便于排除
c、遇到中断的情况要打印警告级别日志,方面后期排除