一群人抢购一件或者多件商品,让我们简单来模拟一下
首先数据库的准备:
因为是抢购商品所以需要商品表
CREATE TABLE `spd` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`shopFont` varchar(255) NOT NULL, -- 商品描述
`shopPrice` int(11) NOT NULL, -- 商品价格
`shopImg` varchar(255) NOT NULL, -- 商品图片
`status` int(11) NOT NULL, -- 商品状态 1、普通出售 2、秒杀商品
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
添加数据:
INSERT INTO `spd` VALUES ('1', '苹果', '100', '图标', '1');
INSERT INTO `spd` VALUES ('2', '旺仔', '200', '图标', '0');
这是我们的商品表
然后在创建秒杀商品的表 : 由于我们是测试所以就不建表之间的关联了,由于有秒杀商品所以我们还需要建立一张秒杀商品的表
CREATE TABLE `spc` (
`id` int(11) DEFAULT NULL, -- 商品id
`shopCount` int(11) DEFAULT NULL --库存
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
添加数据:
INSERT INTO `spc` VALUES ('1', '1');
因为有秒杀商品和普通商品所以查询展示的时候要关联查询
select * from spd insert into spc on spd.id=spc.id where spd.status=2;
这样就可以查询出来所有的数据 然后返回给POJO里面的实体类中
然后可以把数据存入到Redis中替代Session 然后将数据展示到前端则可以看到了商品样式,当我们点击这个抢购的时候应该去跳转到后端http请求的方法中需要的值是点击的这个商品的id一块传入到后端
@RequestMapping("qianggou")
@ResponseBody
String shengcheng(Integer id) {
当我们接收到了这个商品的id下一步就可以去秒杀商品的表中查询库存是否大于0 如果大于0则就可以抢购
可以调用持久层的方法去通过id查询商品的信息返回到实体类中而拿到了这个实体类可以通过get方法去调用商品的库存是否大于0
Spc spc = spCMapper.selectId(id);
if (spc.getShopCount() > 0) {
如果大于0则证明商品还未被抢完可以执行库存-1并且创建订单的操作
// 如果有则去商品库存-1
Integer integer = spCMapper.updateID(id);
<update id="updateID">
update spc set shopCount=shopCount-1 where id=#{id} and shopCount>0
</update>
这是mybatis xml中的方法写法
update spc set :修改spc表
shopCount=shopCount-1: 商品的库存-1
where id=#{id} :
我们前端传过来的商品id是要秒杀哪一件商品所以需要一个确认值
and shopCount>0 :因为我们是多线程的操作 当一个线程进入了这个方法 另一个线程也进入了此方法 第一个线程去查询库存还剩1 第二个线程查询库存也还剩1 都剩下1的情况下两个线程又同时进入了商品大于1的方法 所以必须要有一个判断 当我们第一个线程先去执行了mybatis中的updateID方法 去把商品-1了 则库存中没有了数据 第二个方法进入updateID的时候 虽然也先去-1了 但是到了后面判断 条件的时候 shopCount已经被第一个线程去-1 等于了0 则0==0 !0>0 所以第二个线程不会执行-1的操作也不会创建订单了
接下来可以判断它们是否成功执行了mybatis中的方法并且返回了1 如果没返回1则应对了上面说的话,如果返回了1则为创建订单
boolean falg=integer>0?true:false;
if(falg){
//可以进行创建订单 我们还需要一张订单表
CREATE TABLE `dingdan` (
`id` varchar(255) DEFAULT NULL,
`spid` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`status` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后通过刚才的数据可以直接进行添加到这个表中
return "添加成功订单!"; :然后可以返回
}else{
如果没有添加成功则可以返回
return"订单已经被抢光!";
}
}
}else{
判断的是如果库存小于了0 证明没有库存了直接可以返回被抢光
return "订单已经被抢光!";
}