记录使用jmeter测试扣减库存和修改库存高并发执行是否发生数据不一致问题

问题描述:ERP系统业务方反馈调取修改商城库存接口后,商城库存没有改变,需要验证修改库存和扣减库存并发执行时,是否发生了覆盖,导致数据不一致的问题。

1、测试demo
从代码分析,扣减库存,使用的是悲观锁。

@RestController
@RequestMapping(value = "testreducestorage")
public class TestReduceStorageAction {

    @Autowired
    OrdersService ordersService;

    @RequestMapping(value = "index/{ordersId}",method = RequestMethod.GET)
    public ResultEntity index(@PathVariable int ordersId) throws ShopException {
        ResultEntity resultEntity = new ResultEntity();
        ordersService.testReduceStorage(ordersId);
        resultEntity.setCode(ResultEntity.SUCCESS);
        resultEntity.setMessage("扣减库存成功");
        HashMap<String,Integer> hashMap = new HashMap<>();
        hashMap.put("ordersId",ordersId);
        resultEntity.setData(hashMap);
        return resultEntity;
    }

}
   //测试高并发情况下,扣减库存是否覆盖修改库存
    public void testReduceStorage(int ordersId) throws ShopException {

        //根据订单Id到订单实体表中把商品查询出来,主要是为了减少库存
        List<OrdersGoods> ordersGoodsListByOrdersId = ordersGoodsDao.getOrdersGoodsListByOrdersId(ordersId);
        List<OrdersGoods> seckillGoods              = goodsService.isSeckillGoods1(ordersGoodsListByOrdersId);

        if (seckillGoods.size() > 0) {
            //直接操作减库存即可,不用验证
            buyOrdersService.updateGoodsStorageSales(seckillGoods);
        }

    }

在这里插入图片描述
在这里插入图片描述
2、使用jmeter高并发扣减库存
一个商品初始化库存5000,并发执行100个线程同时扣减库存,循环40次,预期累计扣减库存4000,经过测试库存扣减正常,并没有多扣或少扣,商品最后库存1000,说明扣减库存的悲观锁是正常运行的。
在这里插入图片描述
3、高并发执行扣减库存操作时,同时调取修改库存接口,验证修改库存操作是否被扣减库存操作覆盖。
验证原理:
一个商品初始化库存5000,并发执行100个线程同时扣减库存,循环10次,预期累计扣减库存1000,高并发执行扣减库存操作期间,发起一次修改库存为5000的操作,如果最后库存大于4000,说明修改库存的操作没有被覆盖,如果最后库存等于4000说明修改库存的操作被覆盖。
验证结果:
经多次测试,商品库存都大于4000,修改库存操作并没有被扣减库存操作覆盖的情况。
原因分析:
扣减库存一旦获得了悲观锁,修改库存就不可能先于扣减库存修改数据,所以修改库存操作不会被扣减库存操作覆盖。

4、将服务部署在两个tomcat里面,验证高并发扣减库存锁是否有效。
将web服务部署在两个tomcat,同时发起多线程扣减库存的操作,经多次测试库存没有多扣或者少扣,扣减库存的过程中,发起修改库存的操作,修改库存的操作没有被覆盖。
原因分析:
扣减库存是对数据库加的行锁,两个服务共用一个数据库,数据库加锁是有效的。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u011582840/article/details/108056374