java+mysql商品の買い占め機能を実現します。


購入時に商品の数量が十分かどうかを確認したいです。在庫が残ったら、ユーザーに購入させて成功させます。その後、在庫を変更します。もしユーザが順番に並んで買うなら、もちろん大丈夫です。
しかし、実際の状況では、複数のユーザーが同時に購入し、在庫を確認することができます。これは在庫が一人しかないかもしれません。しかし、在庫がまだ減っていないため、何人かが購入に成功し、在庫がマイナスになって販売超過が発生します。これは多くのユーザーが同じ時点で同時に買う時に現れる可能性が高いです。
そこで私達は順番を調整して、ユーザーが買う時先に在庫を減らします。どうやって減らすべきですか?在庫が一人足りない時も減りますか?
私たちは商品ごとに唯一の購入コードがあると仮定します。(買い占めを始める前に予め生成しておきます。)ユーザーが購入コードの数である彼が買った分の数を奪ったら、ユーザーが購入する時の第一歩は幸運コードの状態に有効から無効に変更し、購入者IDをマークします。
"UPDATE `lottery_number` SET `status` =     ,`user_id` =      Id,`current_time`=      WHERE `goods_id` =      ID AND `status`=     LIMIT      ";
このように実はmysqlは私達に1つの返却結果を与えてくれます。影響行数といいます。つまり、この文の更新は何行のデータに影響していますか?
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 
"; 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() + ")
,"); } // 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;
}
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。