业务场景:
同一个活动,已报名人数不能大于报名人数,每一次报名,已报名人数+1,直至已报名人数等于大于报名人数。
由于存在多个用户在同一个活动的并发情况,采用@version乐观锁来防止已报名人数信息错乱,但在并发的情况下,乐观锁只能保证数据不错乱,并不能保证业务的正常进行,因为用户已经支付活动费用成功,不能因为乐观锁计算已报名人数失败而告知用户支付失败,这个时候需要解决并发情况。
原代码:
TahActivityEntity activityEntity = tahActivityService.selectById(activityId);
if(activityEntity.getActivityPeople()>=activityEntity.getTotalPeople()){
throw new RRException(StatusCodeEnum.ERROR_EXISACTIVITYMAN_ERROR);
}else {
int act= activityEntity.getActivityPeople();
activityEntity.setActivityPeople(act+1);
tahActivityService.updateById(activityEntity);
}
修改后的:
synchronized (activityId.toString().intern()) {
TahActivityEntity activityEntity = tahActivityService.selectById(activityId);
if (activityEntity.getActivityPeople() >= activityEntity.getTotalPeople()) {
throw new RRException(StatusCodeEnum.ERROR_EXISACTIVITYMAN_ERROR);
} else {
int act = activityEntity.getActivityPeople();
activityEntity.setActivityPeople(act + 1);
int version = activityEntity.getVersion();
activityEntity.setVersion(version + 1);
boolean tryadd = tahActivityService.update(activityEntity, new EntityWrapper<TahActivityEntity>().eq("version", version).eq("activity_id", activityEntity.getActivityId()));
if (!tryadd) throw new RRException("预约活动失败,请重试!");
}
}