您的位置:首页 > 其它

对于业务中库存超卖测试

2015-06-29 17:03 281 查看
多并发时,用相应的锁方案保证库存不发生超卖。实现这个方案后,要有相应的场景测试方案。

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

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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: