对于业务中库存超卖测试

多并发时,用相应的锁方案保证库存不发生超卖。实现这个方案后,要有相应的场景测试方案。

很多时候,验证方案非常重要。

java可以利用CountDownLatch测试多并发。CountDownlatch通常用于某个业务线程需要等待其它多个线程完成某个条件后才进行相应操作。

CountDownLatch有countDown及await方法,分别对应减少计数器及当计数器大于0时阻塞当前线程。当计数量等于0时所有调用await方法且被阻塞的线程都被唤醒,然后进行相应操作。

此处用于模拟10个并发用户进行购买,库存初始化为5,看是否会发生超卖。

库存并发方案为对于某个sku的库存增减要求最终减去购买库存后库存量要大于等于0。这步由数据库语句完成。

例,库存更新语句:update skuStock  set 更新后库存=原库存减去购买库存  where skuId=sku ID号   and 原库存减去购买库存后大于0

测试类:

public class StockTest implements ApplicationContextAware {

static {

System.setProperty("spring.profiles.active", "dev");

System.setProperty("configPath", "/home/zhao/work/config");

}

@Autowired

private SkuService skuService;

@Autowired

private SkuStockMapper skuStockMapper;

private static ApplicationContext applicationContext;

private static final CountDownLatch countDownLatch = new CountDownLatch(10);

private static final Logger logger = LoggerFactory.getLogger(StockTest.class);

@Test

public void testStock() throws Exception {

ExecutorService executorService = Executors.newFixedThreadPool(20);

List<Future<Boolean>> futureList = new ArrayList<>();

for (int i = 0; i < 10; i++) {

MockBuyTask mockBuyTask = new MockBuyTask();

futureList.add(executorService.submit(mockBuyTask));

}

int sucCount=0;

for(Future<Boolean> future:futureList){

if(future.get()){

sucCount++;

}

logger.info(future.get().toString());

}

logger.info("共"+sucCount+"人成功购物一件商品");

Assert.assertTrue(sucCount==5);

SkuStock skuStock = skuStockMapper.selectPoByPrimaryKey(7L);

Assert.assertTrue(skuStock != null && skuStock.getSkuId()==8L && skuStock.getCount() == 0);

}

static class MockBuyTask implements Callable<Boolean> {

@Override

public Boolean call() throws Exception {

countDownLatch.countDown();

logger.info("+wait for other man to run,thread:" + Thread.currentThread().getId());

countDownLatch.await();

SkuStock skuStock = new SkuStock();

skuStock.setSkuId(8L);

skuStock.setCount(1);

SkuStockMapper skuStockMapper = applicationContext.getBean(SkuStockMapper.class);

int rowCount = skuStockMapper.updateStockBySkuIdAndCountOfBuy(skuStock);

logger.info("+rowcount:" + rowCount);

return rowCount > 0 ? true : false;

}

}

@SuppressWarnings("static-access")

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

// TODO Auto-generated method stub

this.applicationContext = applicationContext;

}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 04:40:37

对于业务中库存超卖测试的相关文章

秒杀踩坑记:库存超卖

本案例发生在别人身上,觉得有学习借鉴的意义特转载过来记录一下. PM 说有一个类似于抢购的小需求,我们第一反应就想到是典型的防止库存超卖场景,于是理所因当地选用了 Redis 方案.只要保证是原子操作,即可防止库存超卖,自然想到使用 Incr/Decr 这类原子操作. 查看 PHP 的 Redis 扩展关于 Incr 方法的说明: /** * Increment the number stored at key by one. * * @param string $key * @return i

mysql处理高并发,防止库存超卖

先来就库存超卖的问题作描述:一般电子商务网站都会遇到如团购.秒杀.特价之类的活动,而这样的活动有一个共同的特点就是访问量激增.上千甚至上万人抢购一个商品.然而,作为活动商品,库存肯定是很有限的,如何控制库存不让出现超买,以防止造成不必要的损失是众多电子商务网站程序员头疼的问题,这同时也是最基本的问题. 从技术方面剖析,很多人肯定会想到事务,但是事务是控制库存超卖的必要条件,但不是充分必要条件. 举例: 总库存:4个商品 请求人:a.1个商品 b.2个商品 c.3个商品 程序如下: beginTr

转 mysql处理高并发,防止库存超卖

原文地址: mysql处理高并发,防止库存超卖 今天王总又给我们上了一课,其实MySQL处理高并发,防止库存超卖的问题,在去年的时候,王总已经提过:但是很可惜,即使当时大家都听懂了,但是在现实开发中,还是没这方面的意识.今天就我的一些理解,整理一下这个问题,并希望以后这样的课程能多点. 先来就库存超卖的问题作描述:一般电子商务网站都会遇到如团购.秒杀.特价之类的活动,而这样的活动有一个共同的特点就是访问量激增.上千甚至上万人抢购一个商品.然而,作为活动商品,库存肯定是很有限的,如何控制库存不让出

Mysql在高并发情况下,防止库存超卖而小于0的解决方案

背景: 本人上次做申领campaign的PHP后台时,因为项目上线后某些时段同时申领的人过多,导致一些专柜的存货为负数(<0),还好并发量不是特别大,只存在于小部分专柜而且一般都是-1的状况,没有造成特别特别严重的后果,但还是要反思了自己的过错. 这次又有新的申领campaign,我翻看了上次的代码逻辑: 正文: [先select后update] beginTranse(开启事务) try{     $result = $dbca->query('select amount from s_st

(转)mysql处理高并发,防止库存超卖

原文链接:http://blog.csdn.net/caomiao2006/article/details/38568825 今天王总又给我们上了一课,其实mysql处理高并发,防止库存超卖的问题,在去年的时候,王总已经提过:但是很可惜,即使当时大家都听懂了,但是在现实开发中,还是没这方面的意识.今天就我的一些理解,整理一下这个问题,并希望以后这样的课程能多点. 先来就库存超卖的问题作描述:一般电子商务网站都会遇到如团购.秒杀.特价之类的活动,而这样的活动有一个共同的特点就是访问量激增.上千甚至

使用 redis 减少 秒杀库存 超卖思路

由于数据库查询的及插入的操作 耗费的实际时间要耗费比redis 要多, 导致 多人查询时库存有,但是实际插入数据库时却超卖 redis 会有效的减少相关的延时,对于并发量相对较少的 可以一用 1 public function buy($goods_id = 0){ 2 if(!$goods_id){ 3 die("商品不存在!"); 4 } 5 $redis = new Redis(); 6 $redis->connect('127.0.0.1',6379); 7 $stock

项目中遇到的超卖问题及解决办法(使用go做测试工具)

超卖问题:在一个很短的时间内,Mysql的数据状态在 取出,比较,提交,或修改中,另外一个进程访问数据导致的超卖问题. 案例: 1.前端没有做限制,如果用户连续点击签到,那么会有多条数据发送到后端,如果数据状态没有来得及完全修改过来,导致用户的签到数据被多次添加. 2.每天签到用户的前3名用户可以获得一张价值100元的优惠券,如果有多名用户在很短的时间内同时签到,那么就会有多发的问题. 解决案例1:使用数据库的行锁和表锁 DROP TABLE IF EXISTS `crm_concurrency

[转] 基于MySQL的秒杀核心设计(减库存部分)-防超卖与高并发

商品详情页面的静态化,varnish加速,秒杀商品库独立部署服务器这种就略过不讲了.只讨论库存部分的优化 mysql配置层面的优化可以参考我的这篇文章 <关于mysql innodb引擎性能优化的一点心得> 重点设计在数据库层面. 2张表: 第一张:判重表(buy_record),该用户有没秒杀过该商品 字段: id, uid, goods_id, addtime 第二张表:商品表 goods 字段: goods_id   goods_num 方案1: start transaction; s

超卖频发or商品滞销?压倒卖家的最后一根稻草竟是库存!

超卖频发or商品滞销?压倒卖家的最后一根稻草竟是库存! 云南逸神生态茶业有限公司便是一家从最初的单体销售到目前的生产.加工.销售一体化经营,并拥有60多家遍布云南省内.省外城市的直营专卖店.想要发展壮大,除了产品品质之外,更重要的是方法,拥有60多家门店的"逸神"已经出现了库存不准导致的商品超卖,商品滞销带来的库存积压,如无法解决这些问题,发展壮大只能是个遥远的梦.逸神管理者具有长远的眼光,他认为想要把逸神发展成为更大的连锁企业,不仅依靠逸神的销售团队,同时还要借助先进的管理工具实现对