后端接口防止重复提交(确认收货防止重复提交)

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版权协议,转载请附上原文出处链接和本声明。