java - 与 DB 和 URL 交互的并发处理

标签 java concurrency

我有一个计费应用程序,如果客户已经付款,它会在数据库中进行请求检查,如果没有付款,它会访问计费 API,然后更新数据库中的响应。

当客户通过点击“向我开具账单”按钮 3-4 次多次发送请求时,我遇到了问题。所有请求都以毫秒为单位发送到服务器。结果,客户被多次收费,因为结果没有得到更新,因为第一个请求需要一些时间,与此同时,第二个请求从数据库中读取状态并再次进行收费。下面是代码。请让我知道我应该遵循哪些最佳实践来防止同样的事情发生。我已经尝试制作 servlet SingleThreadModel 但它没有帮助

 protected void processRequest(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try (PrintWriter out = response.getWriter()) {
        /* TODO output your page here. You may use following sample code. */
        String mobilenumber = request.getParameter("mobilenumber");
        String param2 = request.getParameter("param2");
        String checkifthecustomerischarged = checkifcharge(mobilenumber);
        if (checkifthecustomerischarged.equals("NOTOK")) {
            String status = hittocharge(mobilenumber, param2);
            int i = updatestatus(mobilenumber, status);
            if (i > 0) {
                out.println("Status Updated ");
            } else {
                out.println("Status Not update Updated ");
            }
        } else {
            out.println("Already Charged");
        }
      }
  }

我在这里检查表格

 private String checkifcharge(String mobilenumber) {
    String st = "NOTOK" ; 
    try {
        Connection conn = null ; 
        ResultSet rs  = conn.createStatement.executeQuery("select sno from table where mobilenumber = "+mobilenumber);
       if(rs.next()){
       st = "OK";
       }

    } catch (Exception e) {
        e.printStackTrace();
     }
  return st ;
  }

我在这里更新状态

   private int updatestatus(String mobilenumber, String status) {
    int st = 0 ; 
    try {
        Connection conn = getConnection() ; 
       st  = conn.createStatement.executeQuery("update table set status =1    where  mobilenumber ="+mobilenumber);

       releaseConnection(conn);
    } catch (Exception e) {
        e.printStackTrace();
    }
 return st ;
}

最佳答案

通常情况下,人们不会只说“向我收费”,而是“向我收费”(例如“2015 年 8 月为手机号码 123 支付的费用”)。我会为每个账单决定一个标识符(例如“08_2015_123”)并将其包含在账单请求和状态表中。然后你可以使用乐观更新,这是

st=statement.executeQuery("update table set status=1 where identifier='08_2015_123' and status<>1")
// if st==0 it probably means bill was previously payed, don't bill again

顺便说一句,即使你完全确定你不能生成这样的标识符,你总是可以在你的表单中生成一些虚拟的随机字段,这样至少你可以识别对同一个按钮的多次快速点击(虽然它赢了'帮助更复杂的情况,例如忘记他一周前付款的用户)。但是,对于计费,我会努力寻找合适的标识符。

关于java - 与 DB 和 URL 交互的并发处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32063855/

相关文章:

java - 如何在OkHttp中设置cookie格式?

java - 如何以编程方式从另一个程序中关闭在 Windows 中运行的特定 Java 应用程序?

java - 如何使用 JAVA 以编程方式填写 Web 表单?

python - 我应该担心在多线程 python 脚本中并发访问字典吗?

concurrency - Perl6 制作一个可观察的计时器

java - 使用 AWS SSO 时 AWS Java SDK 找不到配置文件

java - Spring @Transaction 和@Async 数据库操作的用法

java - 尝试访问临界区的三种类型的线程

concurrency - 为什么我所谓的并行 go 程序不是并行的

Java JNI : Can't load dependent libraries