1:在调用接口时候肯定会出现AB同事请求接口的问题,当时我在做订单确认收货时候就遇到了这种问题,所以我的解决办法是加上锁来解决,在这里我选择用Lock 里的ReentrantLock(),在用户请求方法时候,获取到用户id,放入lock,这也同一个接口如果是2个相同用户AB同时确认收货时候,先到先处理,后来后处理,拿到钥匙之后先进行一个验证,验证此用户是否已经收货,预防一直在收货,恶意接口调用,如果成功确认收货那么通过finally 来释放锁,同时移除锁在Lock里的userId。这也就完成一个确认收货防止重复提交的一个操作,如果是分布式的一个接口,那么可以参考一些分布式锁的一些例子,此例子只当做单个服务器做一个防止重复提交。
private Map<String, Lock> locks = new ConcurrentHashMap<>();
Lock nlock = new ReentrantLock();
Lock lock = locks.putIfAbsent(cancelOrderPar.getUserId(), nlock);
if (lock == null) {
lock = nlock;
}
boolean removeLock = false;
lock.lock();
try {
//查看订单状态预防非法调用
OrderExample orderExample=new OrderExample();
orderExample.createCriteria().andParentIdEqualTo(cancelOrderPar.getParentId());
List<Order> orderList=orderMapper.selectByExample(orderExample);
for (Order order:orderList){
if (!order.getStatus().equals(3)){
return setResultError("该状态不能确认收货成功");
}
}
//根据订单号查询分享人id
String shareUserId=null;
String findShareUserIdByParentId=this.orderExtMapper.findShareUserIdByParentId(cancelOrderPar.getParentId());
if (!StringUtils.isBlank(findShareUserIdByParentId)){
shareUserId=findShareUserIdByParentId;
}
ResponseBase<UserModel> gainerData=userClient.findRoot(cancelOrderPar.getUserId(),shareUserId);
String gainerId=null;
if (gainerData!=null&&gainerData.getData()!=null){
gainerId=gainerData.getData().getId();
}
this.orderExtMapper.upOrderByUserId(cancelOrderPar.getUserId(),4,cancelOrderPar.getParentId(),gainerId);
removeLock = true;
} finally {
lock.unlock();
if (removeLock) {
locks.remove(cancelOrderPar.getUserId());
}
}
版权声明:本文为qq_30667039原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。