• 大批量推送项目日记(三):正确防止接口被短时间内多次调用的方法


    2020.8.5

    今天,本人发现了一个问题:

    本人编写的代码提供了一个接口(url),当接口被调用时,会先从数据库中查找status不为1的记录(也就是未推送与推送失败的记录),获取每行的userID,然后把userID当做参数发送一个http请求,发送完毕后根据返回信息修改status,记为1(推送成功)或2(推送失败),以此实现了给用户推送信息。

    正常情况下,调用一次本人的接口后,status会被修改,成功的改为1,失败的改为2;不影响下次调用。

    但是,如果有人在短时间内多次调用本人的接口,会造成多个线程从数据库中查到相同的数据(此时status还没有来得及被修改),然后多个线程发送相同的http请求,就会造成一个用户收到多个相同的推送信息。

    为了解决这个问题,本人想到了一个方法,代码如下(自测没有问题):

    //记录当前线程的变量,不允许多个线程同时运行
    public static Thread nowThread = null;
    
    ......
    
    //线程主方法
    public void pushTask(){
    
      //如果有正在执行的线程,新线程就不继续执行
    
      if(nowThread != null && nowThread.isAlive()){
        LOG.info("当前存在正在执行的线程,本次线程不执行,请稍后再试");
        return;
      }
    
      else{
        nowThread = Thread.currentThread();
      }
      
      //主要代码省略
      ......
    
      //线程执行完毕,置空
      nowThread = null;
    
    }

    1.上方的代码增加了一个static类型的Thread对象,保存上一次执行过的线程对象

    2.当一个新的线程执行到该方法时,进行判断,如果上一次执行的线程不为null且存活,则自己不再执行,直接return

    3.否则,新线程把自己的对象保存到nowThread

    4.线程执行完成时,将nowThread置为null(这个好像不写也可以)

    5.即使线程执行到一半意外停止,也不会影响新线程的执行,新线程根据isAlive()方法可以判断出来上一个线程是否存活。

    -----------------------------------------------------------------------------------------------------------------------------

    这个方法目前自测没有发现问题,也许不是最好的解决方法,但是应该能解决问题了。

    如果大家有更好的解决方法,欢迎在评论区留言,谢谢!

  • 相关阅读:
    c# winform treelistview的使用(treegridview)
    基于Windows服务的聊天程序
    .Net Core集成Office Web Apps(二)
    .Net Core集成Office Web Apps(一)
    .Net页面局部更新的思考
    C#下载歌词文件
    jquery导航栏
    Select2下拉框总结
    数位dp入门(内容一样,新版格式)
    我的emacs简易配置
  • 原文地址:https://www.cnblogs.com/codeToSuccess/p/13906221.html
Copyright © 2020-2023  润新知