java秒杀高并发------ 秒杀功能实现

数据库设计

商品表

CREATE TABLE `miaosha`.`Untitled`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `goods_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `goods_title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `goods_img` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `goods_detail` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '商品详情介绍',
  `goods_price` decimal(10, 2) DEFAULT 0.00 COMMENT '商品单价',
  `goods_stock` int(11) DEFAULT 0 COMMENT '商品库存,-1表示没有限制',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

订单表

CREATE TABLE `miaosha`.`Untitled`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) DEFAULT NULL,
  `goods_id` bigint(20) DEFAULT NULL,
  `delivery_addr_id` bigint(20) DEFAULT NULL COMMENT '收货地址ID',
  `goods_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '商品名称',
  `goods_count` int(11) DEFAULT 0 COMMENT '商品数量',
  `goods_price` decimal(10, 2) DEFAULT 0.00 COMMENT '商品单价',
  `order_channel` tinyint(4) DEFAULT 0 COMMENT '1PC,2Android,3Ios',
  `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '订单状态,0新建支付,1已支付,2已发货,3已收货,4已退款,5已完成',
  `create_date` datetime DEFAULT NULL COMMENT '订单创建时间',
  `pay_date` datetime DEFAULT NULL COMMENT '支付时间',
    PRIMARY KEY (`id`) USING BTREE) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

秒杀商品表(把秒杀拉出来,单独做一个表,以后有其他活动在拉出来做一个表)

CREATE TABLE `miaosha`.`Untitled`  (
  `id` bigint(20) NOT NULL,
  `goods_id` bigint(20) DEFAULT NULL,
  `miaosha_price` decimal(10, 2) DEFAULT 0.00 COMMENT '秒杀价',
  `stock_count` int(11) DEFAULT NULL COMMENT '库存数量',
  `start_date` datetime DEFAULT NULL COMMENT '秒杀开始时间',
  `end_date` datetime DEFAULT NULL COMMENT '秒杀结束时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Fixed;

秒杀订单表

秒杀订单表


CREATE TABLE `miaosha`.`Untitled`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `order_id` bigint(20) NOT NULL,
  `goods_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Fixed;

对应创建实体类
对商品信息和对应的商品秒杀信息获取
一起获取

@Mapper
public interface GoodsDao {
  @Select("select g.*,mg.stock_count,mg.start_date,mg.end_date from miaosha_goods mg left join goods g on mg.goods_id = g.id")
    public List<GoodsVo> listGoodsVo();
    }

单独创建了返回的VO

创建的GoodsVO是 goods商品表和一些秒杀信息的实体类,用于存储查询返回的数据

将返回的数据写入 模板就可以了。

<div class="panel panel-default">
  <div class="panel-heading">秒杀商品列表</div>
  <table class="table" id="goodslist">
   <tr><td>商品名称</td><td>商品图片</td><td>商品原价</td><td>秒杀价</td><td>库存数量</td><td>详情</td></tr>
   <tr  th:each="goods,goodsStat : ${goodsList}">  
                <td th:text="${goods.goodsName}"></td>  
                <td ><img th:src="@{${goods.goodsImg}}" width="100" height="100" /></td>  
                <td th:text="${goods.goodsPrice}"></td>  
                <td th:text="${goods.miaoshaPrice}"></td>  
                <td th:text="${goods.stockCount}"></td>
                <td><a th:href="'/goods/to_detail/'+${goods.id}">详情</a></td>  
     </tr>  
  </table>
</div>

这里写图片描述

商品详情
这里写图片描述

秒杀功能实现

提交的时候就交了一个id

首先我们要判断用户是否登录,
然后判断 根据这个商品ID获取商品的库存是否还有
是否已经秒杀成功了(根据订单判断)
没有就要减少库存,并且增加订单和秒杀订单。

@RequestMapping("/do_miaosha")
public String list(Model model, MiaoshaUser user, @RequestParam("goodsId") long goodsId){
    //没登录就跳转到登录页面
    model.addAttribute("user",user);
    if (user==null){
        return "login";
    }
    //判断库存
    GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
    int stock = goods.getGoodsStock();
    if (stock<=0){//没有库存了.
        model.addAttribute("errmsg", CodeMsg.MIAO_SHA_OVER.getMsg());
        return "miaosha_fail";
    }
    //判断是否已经秒杀到了
    MiaoshaOrder order  = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(),goodsId);
    if(order!=null){
        model.addAttribute("errmsg",CodeMsg.REPEATE_MIAOSHA.getMsg());
        return "miaosha_fail" ;
    }else {
        //秒杀
        //减库存 下订单 写入秒杀订单
        OrderInfo orderInfo = miaoshaService.miaosha(user,goods);
        model.addAttribute("orderInfo",orderInfo);
        model.addAttribute("goods",goods);
        return "order_detail";
    }

秒杀的操作写在秒杀service方法中

每个service中的最好只使用自己的dao
如果要使用别的dao最好注入别的 service!!!

@Service
public class MiaoshaService {

    @Autowired
    GoodsService goodsServic;

    @Autowired
    OrderService orderService;

    @Transactional
    public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods){
        //减少库存 下订单 写入秒杀订单
        goodsServic.reduceStock(goods);
        //订单表,秒杀表
        OrderInfo orderInfo = orderService.createOrder(user,goods);



        return orderInfo;
    }

个订单并且将插入的id封装到原来的对象中
@SelectKey(keyColumn=”id”, keyProperty=”id”, resultType=long.class, before=false, statement=”select last_insert_id()”)



@Insert("insert into order_info(user_id, goods_id, goods_name, goods_count, goods_price, order_channel, status, create_date)values("
        + "#{userId}, #{goodsId}, #{goodsName}, #{goodsCount}, #{goodsPrice}, #{orderChannel},#{status},#{createDate} )")
        @SelectKey(keyColumn="id", keyProperty="id", resultType=long.class, before=false, statement="select last_insert_id()")long insert(OrderInfo orderInfo);

成功后就会跳转到 订单详情。

猜你喜欢

转载自blog.csdn.net/qq_28295425/article/details/80240128