java+mysql实现商品抢购功能

我们希望有人购买时检查商品数量是否足够,如果库存有剩余那么就让用户购买成功,之后变更库存,假如用户排队挨个购买这样当然没有问题。

可是实际情况下,可能是用户多个用户同时来购买,同时检查库存,这是可能库存仅够其中一人购买,但是由于库存还没减掉,就会出现几个人都购买成功,然后库存减为负数出现超卖的情况。这在大量用户在同一时间点同时购买时极可能出现。
于是我们调整一下顺序,有用户购买时我们先减掉库存,那你肯定要问,怎么减?库存不够一个人的时候也减?
我们假设每份商品有一个唯一的购买码(开始抢购前预先生成),用户抢到购买码的数量即他买到的份数,那么有用户购买时我们第一步就是给幸运码的状态由有效更改为无效,并为其标记上其购买者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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JavaWeb实现简单查询商品功能

    本文实例为大家分享了JavaWeb实现简单查询商品功能的具体代码,供大家参考,具体内容如下 CustomerServlet.java package com.subing.web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet

  • java使用hadoop实现关联商品统计

    最近几天一直在看Hadoop相关的书籍,目前稍微有点感觉,自己就仿照着WordCount程序自己编写了一个统计关联商品. 需求描述: 根据超市的销售清单,计算商品之间的关联程度(即统计同时买A商品和B商品的次数). 数据格式: 超市销售清单简化为如下格式:一行表示一个清单,每个商品采用 "," 分割,如下图所示: 需求分析: 采用hadoop中的mapreduce对该需求进行计算. map函数主要拆分出关联的商品,输出结果为 key为商品A,value为商品B,对于第一条三条结果拆分结

  • Java实现商品的查找、添加、出库、入库操作完整案例

    本文实例讲述了Java实现商品的查找.添加.出库.入库操作.分享给大家供大家参考,具体如下: package com.jredu.oopch08; public class Goods1 { private int id; private String name; private double price; private String uom; private int balance; public Goods1(int id, String name, double price, Strin

  • java实现超市商品库存管理平台

    本文实例为大家分享了java商品库存管理平台的具体代码,供大家参考,具体内容如下 1.完成超市商品初始化.创建商品,将商品添加到集合 2.显示来到超市能做的操作,也就是显示主菜单 3.根据接收到的功能选项,执行对应的功能 3.1.库存商品查询 3.2.添加新商品     3.3.删除商品 3.4.修改商品 3.5.退出系统,结束main方法的运行 4.循环,回到  2. 显示主菜单 以添加水果为例:对商品信息进行封装,编写FruitItem.java文件 public class FruitIt

  • Java基于JDBC实现事务,银行转账及货物进出库功能示例

    本文实例讲述了Java基于JDBC实现事务,银行转账及货物进出库功能.分享给大家供大家参考,具体如下: 1. 转账业务 转账必须执行2个sql语句(update更新)都成功的情况下,提交事务,如果有一个失败,则2个都回滚事务 2. 事务应该具有4个属性:原子性.一致性.隔离性.持久性.这四个属性通常称为ACID特性. ① 原子性(atomicity).一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做. ② 一致性(consistency).事务必须是使数据库从一个一致性状

  • Java使用策略模式解决商场促销商品问题示例

    本文实例讲述了Java使用策略模式解决商场促销商品问题.分享给大家供大家参考,具体如下: 一 模式定义 策略模式:定义一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化. 二 模式举例 1 模式分析 我们借用商场促销商品来说明这一模式. 2 策略模式静态类图 3 代码示例 3.1 创建策略接口一IStrategy package com.demo.strategy; /** * 策略接口 * * @author * */ public inter

  • java实现商品管理系统

    本文实例为大家分享了java实现商品管理系统的具体代码,供大家参考,具体内容如下 功能要求: 完成"小商品管理系统"的架构设计 要求:利用集合存储若干商品对象 ----小商品管理系统---- 0. 退出 1. 录入商品基本信息 2. 显示商品信息 3. 商品入库(增加数量) 4. 商品出库(减少数量) 5. 修改商品价格 6. 所有产品的总价格(单价*数量) import java.util.ArrayList; import java.util.Scanner; public cla

  • java实现商品信息管理系统

    超市商品管理系统,供大家参考,具体内容如下 题目要求 超市中商品分为四类,分别是食品.化妆品.日用品和饮料.每种商品都包含商品名称.价格.库存量和生产厂家.品牌等信息.主要完成对商品的销售.统计和简单管理.这个题目相对简单,可以用一张表实现信息的保存和处理,因此不再给出数据库设计参考. 功能要求 (1)销售功能. 购买商品时,先输入类别,然后输入商品名称,并在库存中查找该商品的相关信息.如果有库存量,输入购买的数量,进行相应计算.如果库存量不够,给出提示信息,结束购买. (2)商品简单管理功能.

  • JAVAEE model1模型实现商品浏览记录(去除重复的浏览记录)(一)

    在javaee中Model1模型是以jsp页面为中心的,jsp既要对浏览器的request做出逻辑处理(使用javabean),访问数据库也要显示出相关的页面. 在model1模型中,没有servlet. Model1结果图如下: Model1的可维护性  可扩展性都是较差的  只适合小项目. 首先运行结果 goods.jsp <%@page import="entity.Items"%> <%@page import="dao.ItemsDao"

  • java+mysql实现商品抢购功能

    我们希望有人购买时检查商品数量是否足够,如果库存有剩余那么就让用户购买成功,之后变更库存,假如用户排队挨个购买这样当然没有问题. 可是实际情况下,可能是用户多个用户同时来购买,同时检查库存,这是可能库存仅够其中一人购买,但是由于库存还没减掉,就会出现几个人都购买成功,然后库存减为负数出现超卖的情况.这在大量用户在同一时间点同时购买时极可能出现. 于是我们调整一下顺序,有用户购买时我们先减掉库存,那你肯定要问,怎么减?库存不够一个人的时候也减? 我们假设每份商品有一个唯一的购买码(开始抢购前预先生

  • JavaScript实现的商品抢购倒计时功能示例

    本文实例讲述了JavaScript实现的商品抢购倒计时功能.分享给大家供大家参考,具体如下: <html> <head> <meta charset="utf-8"> <title>JS抢购倒计时</title> </head> <body> <span id="times" > <SCRIPT LANGUAGE="JavaScript">

  • Java+swing+Mysql实现商品销售管理系统

    目录 前言 数据库的建立 Java系统 entity包 data包 Login包 windows包 主系统类 前言 临近期末做了一个商品销售管理系统,分享下,全部源码在码云,需要自取,博客只分享部分代码(太多了). 数据库的建立 我们使用Navicat Premium 15连接mysql,建立如下九张表. 得到如下视图(看上去似乎有点乱了) 因为register是一个注册表,所以不参与视图里的连接. 各种表的情况如上所示,当然你也可以用sql语句写. 这个是我导出来的sql语句,由于我也没试过,

  • Android实现仿淘宝购物车增加和减少商品数量功能demo示例

    本文实例讲述了Android实现仿淘宝购物车增加和减少商品数量功能.分享给大家供大家参考,具体如下: 在前面一篇<Android实现的仿淘宝购物车demo示例>中,小编简单的介绍了如何使用listview来实现购物车,但是仅仅是简单的实现了列表的功能,随之而来一个新的问题,买商品的时候,我们可能不止想买一件商品,想买多个,或许有因为某种原因点错了,本来想买一件来着,小手不小心抖了一下,把数量错点成了三个,这个时候就涉及到一个新的功能,那就是增加和减少商品的数量,今天这篇博文,小编就来和小伙伴们

  • SSH框架网上商城项目第9战之添加和更新商品类别功能实现

    上一节我们做完了查询和删除商品的功能,这一节我们做一下添加和更新商品的功能. 1. 添加商品类别 1.1 添加类别的UI设计         我们先说一下思路:首先当用户点击"添加商品"时,我们应该弹出一个"添加商品"的UI窗口(注意这里不是跳转到新的jsp,EasyUI只有一个页面),弹出这个"添加商品"的窗口后,应该锁住它父类的所有窗口(即点击其他地方无效,只能操作添加商品的窗口),等用户填好了信息后,在新弹出来的窗口上点击"添加&

  • Java编程调用微信支付功能的方法详解

    本文实例讲述了Java编程调用微信支付功能的方法.分享给大家供大家参考,具体如下: 微信开发文档地址:https://mp.weixin.qq.com/wiki/home/ 从调用处开始 我的流程: 1.点击"支付"按钮,去后台 --> 2.后台生成支付所需数据返回页面 --> 3.页面点击"确认支付"调用微信支付js.完成支付功能. 支付按钮 <div class="button" id="pay" onc

  • php+ajax实现商品对比功能示例

    本文实例讲述了php+ajax实现商品对比功能.分享给大家供大家参考,具体如下: 商品对比调用的JS文件(包含了商品对比框浮动JS): /*浮动窗口*/ (function(){ var n=10; var obj=document.getElementById("goods-compare"); if(!obj){ return false; } var x=0; window.onscroll=function(){ obj.style.top=(document.body.scr

  • 基于Docker结合Canal实现MySQL实时增量数据传输功能

    Canal的介绍 Canal的历史由来 在早期的时候,阿里巴巴公司因为杭州和美国两个地方的机房都部署了数据库实例,但因为跨机房同步数据的业务需求 ,便孕育而生出了Canal,主要是基于trigger(触发器)的方式获取增量变更.从2010年开始,阿里巴巴公司开始逐步尝试数据库日志解析,获取增量变更的数据进行同步,由此衍生出了增量订阅和消费业务. 当前的Canal支持的数据源端MySQL版本包括:5.1.x .5.5.x .5.6.x.5.7.x.8.0.x. Canal的应用场景 目前普遍基于日

  • Java实现邮件找回密码功能

    本文实例为大家分享了Java实现邮件找回密码功能的具体代码,供大家参考,具体内容如下 1.有个需求就是,忘记密码后通过邮箱找回.现在的系统在注册的时候都会强制输入邮箱,其一目的就是 通过邮件绑定找回,可以进行密码找回.通过java发送邮件的功能我就不说了,重点讲找回密码. 2.参考别人的思路:发送邮件→请求邮件里的URL→验证url→{验证成功修改密码,不成功跳转到失败页面} 重点就是如何生成这个url和如何解析这个url. 需要注意的是一个url只能修改一次密码,当同一帐号发送多封邮件,只有最

  • mysql外键基本功能与用法详解

    本文实例讲述了mysql外键基本功能与用法.分享给大家供大家参考,具体如下: 本文内容: 什么是外键 外键的增加 外键的修改和删除 外键的约束模式 首发日期:2018-04-12 什么是外键: 外键就是表中存在一个字段指向另外一个表的主键,那么这个字段就可以称为外键. 一张表可以有多个外键. 外键用于约束表与表之间的关系,可以说外键是表之间的映射关系,这个关系可以帮助我们处理表之间关系的紧密性和存在性(比如学生表的cid班级号与班级表的id建立关联,cid应该不能为不存在的,如果不增加外键cid

随机推荐