java+mysql實現商品搶購功能,javamysql商品搶購

來源:互聯網
上載者:User

java+mysql實現商品搶購功能,javamysql商品搶購

我們希望有人購買時檢查商品數量是否足夠,如果庫存有剩餘那麼就讓使用者購買成功,之後變更庫存,假如使用者排隊挨個購買這樣當然沒有問題。

可是實際情況下,可能是使用者多個使用者同時來購買,同時檢查庫存,這是可能庫存僅夠其中一人購買,但是由於庫存還沒減掉,就會出現幾個人都購買成功,然後庫存減為負數出現超賣的情況。這在大量使用者在同一時間點同時購買時極可能出現。
於是我們調整一下順序,有使用者購買時我們先減掉庫存,那你肯定要問,怎麼減?庫存不夠一個人的時候也減?
我們假設每份商品有一個唯一的購買碼(開始搶購前預先產生),使用者搶到購買碼的數量即他買到的份數,那麼有使用者購買時我們第一步就是給幸運碼的狀態由有效更改為無效,並為其標記上其購買者ID

複製代碼 代碼如下:"UPDATE `lottery_number` SET `status` = 失效狀態,`user_id` = 購買者使用者Id,`current_time`= 時間戳記  WHERE `goods_id` = 搶購的商品ID AND `status`=有效狀態 LIMIT 購買份數 ";
這樣其實mysql會給我們一個返回結果,叫做影響行數,就是說這條語句更新影響了多少行的資料,這個影響行數就是他實際購買到的商品份數,如果影響行數為0,就說明一份也沒購買成功,也就意味著商品已經搶購完成了。

java實現:

/** * 產生商品的購買碼<大量資料插入> * * @param goodsIssue * @author Nifury */public void insertLotteryNumbers(GoodsIssue goodsIssue) { String prefix = "INSERT INTO `lottery_number` (`goods_id`, `periods`,`luck_number`, `create_time`, `status`, `issue_id` ) VALUES \n"; Timestamp now = new Timestamp(System.currentTimeMillis()); Connection con = null; try {  con = jdbcTemplate.getDataSource().getConnection();  con.setAutoCommit(false);  PreparedStatement pst = con.prepareStatement("");  Long total = goodsIssue.getTotalShare();// 總人次  for (int i = 0; i < total; i += 10000) {// 1萬條提交一次   StringBuffer suffix = new StringBuffer();   List<Integer> numbers = new ArrayList<Integer>();   for (int j = 0; j < 10000 && i+j < total; j++) {    numbers.add(10000001 + i + j);   }   Collections.shuffle(numbers);//打亂幸運碼   for (int n = 0,length = numbers.size(); n < length; n++) {    suffix.append("(" + goodsIssue.getGoodsId() + ","      + goodsIssue.getPeriods() + ","      + numbers.get(n) + ",'" + now.toString() + "',"      + 1 + "," + goodsIssue.getIssueId() + ")\n,");   }   // 構建完整sql   String sql = prefix + suffix.substring(0, suffix.length() - 2);   pst.addBatch(sql);   pst.executeBatch();   con.commit();  }  con.setAutoCommit(true);// 還原  pst.close();  con.close(); } catch (Exception e) {  e.printStackTrace();  try {// 交易回復   con.rollback();   con.setAutoCommit(true);   con.close();  } catch (SQLException e1) {   e1.printStackTrace();  }// 還原 }}

分配購買碼(我們的業務需要給購買使用者展示購買碼,所以有返回)

/** * 通過商品issue_id(每期每個商品有唯一issue_id)來隨機擷取購買碼(使用的購買碼會設為失效狀態) * @param issueId * @param amount 需要擷取的購買碼的數量 * @param userId * @return LotteryNumber對象列表 * @author Nifury 2016-7-22 */public List<LotteryNumber> queryByNewIssueId2(Long issueId, Long amount,Long userId) { List<LotteryNumber> numberList = new ArrayList<LotteryNumber>(); try {  long currentTime=System.currentTimeMillis();  String updateUserId = "UPDATE `lottery_number` SET `status` = 0,`user_id` = ?,`current_time`= ? WHERE `issue_id` = ? AND `status`=1 LIMIT ? ";  int rownum=jdbcTemplate.update(updateUserId, userId, currentTime, issueId, amount );  if(rownum>0){//還有剩餘有效購買碼   Object[] buyargs={issueId, userId ,currentTime};   numberList = jdbcTemplate.query(QUERY + " WHERE `issue_id` = ? AND `status` = 0 AND `user_id` = ? AND `current_time`= ?",     buyargs, LotteryNumberMapper);  } } catch (DeadlockLoserDataAccessException e) {  System.out.println("----分配購買碼出現死結,使用者分得0個購買碼-----"); } return numberList;}

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.