秒杀商品(Java详解)-乐观锁

一群人抢购一件或者多件商品,让我们简单来模拟一下

首先数据库的准备:

因为是抢购商品所以需要商品表

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 "订单已经被抢光!";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值