问题:在多线程下会出现积分在扣到为0的情况还会出现扣到积分负数。
问题分析:在代码中判断用户积分在扣除积分符合后,准备执行数据库扣除积分总量,会在多线程环境下,被提前一步执行了其他扣除积分的操作。接下来执行当前扣除积分会出现积分超扣问题。
java代码
public int dercPoint(Long userId, String typeName, Integer num) {
String key = RedisKey.POINTS_CONFIG_HASH.getPrefix();
// 获取redis中的积分
PointsConfig pointsConfig = JSON.parseObject(redisTemplate.opsForHash().get(key, typeName).toString(),PointsConfig.class);
int effectCount = pointsMapper.dercPoint(userId,pointsConfig.getPoints()*num);
if(effectCount > 0){
// 记录添加记录历史
PointsDetail pointsDetail = new PointsDetail();
pointsDetail.setUserId(userId);
pointsDetail.setPointsChange(pointsConfig.getPoints()*num);
pointsDetail.setChangeTime(new Date());
pointsDetail.setOperationType(pointsConfig.getOperationType());
pointsDetail.setRemarks(pointsConfig.getRemark());
pointsDetailMapper.add(pointsDetail);
}
return effectCount;
}
SQL代码
<update id="dercPoint">
update t_points set total_points = total_points - #{points}
where user_id = #{userId} and total_points > 0
</update>
解决方案:在做update操作时可以使用更新操作会返回影响行数去判断,该操作是否执行成功,相当于在MySQL中做一次判断
