2015-08-18 32 views
3

我有一個賬單應用程序,如果客戶已經付款,如果沒有付款,它會觸發一個賬單API,然後更新數據庫中的響應,並在數據庫中進行請求檢查。使用數據庫和URL進行併發處理

當客戶多次點擊「Bill me」按鈕多次發送請求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 ; 
} 
+0

我真心希望這是代碼沒有被用於實際計費。 – Kayaman

+0

實際上這不是現場,我正在試圖讓一個..讓我知道你的想法。 –

+0

我認爲你對此太缺乏經驗。結算涉及金錢,並且沒有人會將資金信任給無法正確處理交易的軟件。 – Kayaman

回答

2

正常情況下,人不不要只說「給我開賬單」,而要「給我一些具體的東西」(例如「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 

行BTW,即使你是絕對肯定你不能產生這樣的標識符,你總是可以生成表單中的一些虛擬隨機場,所以至少你可以在同一個按鈕上標識多個快速點擊(儘管它不會幫助更復雜的情況,例如忘記他在一週前付款的用戶)。但是,如果計費,我會盡力找到一個合適的標識符。

+0

hi pelit,感謝您的回覆,但我期待將同步,線程安全,單線模型生活功能,還有計費模式,只需點擊他的移動帳戶即可直接向其收費。 –

+1

嗨,恐怕悲觀鎖定(同步/線程安全等)將無法幫助,如果問題來自多個點擊*移動*。考慮一下......你會鎖定什麼,什麼時候鎖定?這就像鎖定觸發器應該是「我在移動設備上呈現按鈕的那一刻」,這將是一場性能噩夢。 –

+1

順便說一句,如果你正在尋找一個快速的解決方案,只需多次點擊 - 你可以在第一次點擊後(並在發送我們的請求之前)禁用按鈕。但是我認爲,對於大型圖片來說,最好能夠確定您的結算方式。 –