Java电商库存扣减实现
业务需求:做了一个商城系统,在下单库存扣减时存在超卖问题,决定采用乐观锁保证数据一致。
·
业务需求:做了一个商城系统,在下单库存扣减时存在超卖问题,决定采用乐观锁保证数据一致。
1、库存所在表添加version乐观锁字段
2、实体类字段上面使用mybatis的@Vesion注解
(这个注解会帮你判断并且自动+1,使用注解记得先查询再update,生效的前提是获取上一次的版本号,也可以自己实现。*注意:如果使用LambdaUpdateWrapper去更新,实体上的@Vesion将失效,要向我下面一样写完全条件)
3、如果乐观锁生效,触发重试机制,重试次数可以根据自己业务决定。
4、话不多说,上代码(只有核心代码块)
/**
* 库存扣减
*
* @param number 执行次数,用于并发情况下重试标识
* @param ssOrderItem sku明细信息
*/
private void stocks(SsOrderItem ssOrderItem, int number) {
// 重试超过三次,返回失败
if (number > 3) {
throw new RuntimeException("购买失败,请重新查询商品!");
}
SsGoodsSku byId = ssGoodsSkuService.getById(ssOrderItem.getSkuId());
if (byId.getActualStocks() - ssOrderItem.getBuyNumber() < 0) {
throw new RuntimeException(String.format("商品库存不足【剩余%s,购买%s】!", byId.getActualStocks(), ssOrderItem.getBuyNumber()));
}
LambdaUpdateWrapper<SsGoodsSku> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(SsGoodsSku::getId, ssOrderItem.getSkuId());
updateWrapper.eq(SsGoodsSku::getVersion, byId.getVersion());
updateWrapper.set(SsGoodsSku::getVersion, byId.getVersion() + 1);
updateWrapper.set(SsGoodsSku::getActualStocks, byId.getActualStocks() - ssOrderItem.getBuyNumber());
boolean update = ssGoodsSkuService.update(updateWrapper);
if (!update) {
stocks(ssOrderItem, number + 1);
}
}
此方式适用于并发量一般的业务。高并发下会有一定性能压力噢~~~
更多推荐
已为社区贡献1条内容
所有评论(0)