项目工程代码来自:https://gitee.com/flowers-bloom-is-the-sea/PessimisticLock/tree/version1.0/
核心代码
@Service
public class GoodsOrderServiceImpl extends ServiceImpl<GoodsOrderMapper, GoodsOrder> implements GoodsOrderService {
@Autowired
private IGoodsService goodsService;
@Override
public R buyOneGoods(Long goodsId, Long userId) {
synchronized (userId.toString().intern()) {
return createGoodsOrder(goodsId, userId);
}
}
@Transactional
public R<String> createGoodsOrder(Long goodsId, Long userId) {
QueryWrapper<GoodsOrder> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("goods_id", goodsId)
.eq("user_id", userId);
GoodsOrder goodsOrder = getOne(queryWrapper);
if (goodsOrder != null) return R.fail("can not get the goods");
Goods goods = goodsService.getById(goodsId);
if (goods == null || goods.getStock() <= 0) return R.fail("has not any stock");//step 1
boolean success = goodsService.update()
.setSql("stock = stock - 1")
.eq("id", goodsId)
.gt("stock", goods.getStock() / 3)//这里比较前后的数据是否相等,相等就可以修改库存
.update();//step 2
if (!success) {
return R.fail("has not any stock");
}
goodsOrder = new GoodsOrder();
goodsOrder.setGoodsId(goodsId);
goodsOrder.setUserId(userId);
save(goodsOrder);
return R.success("buy one success");
}
}
测试1:
当前goods表只有1条数据:
id stock
------ --------
1 1000
而goods_order表还没有数据。
使用postman:
测试接口:http://localhost:8081/goods/buyGoodByUserId/1/1
结果发现goods表库存减一。
goods_order表增加一个数据:
id user_id goods_id
------ ------- ----------
1 1 1
再将goods表的库存增加到1000,使用jmeter开启1000线程测试同一个接口:
正常情况应该是没办法增加数据到goods_order表的,goods表的库存也是没有变化。
实验结果:
1、jmeter聚合报告
2、数据库的数据无任何变化
说明这个是成功了
测试2:
先将goods_order表的数据清空,再使用jmeter开启1000线程接口测试:
正常情况应该是1个数据插入了goods_order表,库存也是减一而已。
结果:
goods表的数据:
id stock
------ --------
1 999
goods_order的数据:
id user_id goods_id
------ ------- ----------
2 1 1
jmeter的聚合报告:
项目评价:
已经实现1人一单的功能。