问题复现:
@Autowired
private LockService lockService;
@Autowired
private CommoditySkuActivityStockRepository stockRepository;
@Transactional(rollbackFor = Exception.class)
public void testTrans() {
testLock();
}
public void testLock() {
long id = 1L;
lockService.tryLock(new DefaultPlatformNameGenerator("lockKey" + id), () -> {
CommoditySkuActivityStock stock = stockRepository.findOne(id);
if (stock.getStock() <= 0) {
throw new ChdIgnorableException("库存不足");
}
stockRepository.save(stock);
});
}
问题分析:
由于在事务里面加锁,第1个请求进来的时候,商品库存是1,这个时候改成0,但是还没提交数据库,testLock()方法走完之后,分布式锁释放,注意这个时候事务还没提交,商品库存还是1,第2个请求过来的时候,认为库存还是1,导致没报错,出现超卖的情况。
解决方案:
将事务包在分布式锁里面
@Autowired
private LockService lockService;
@Autowired
private CommoditySkuActivityStockRepository stockRepository;
public void testLock() {
long id = 1L;
lockService.tryLock(new DefaultPlatformNameGenerator("lockKey" + id), () -> {
testLock();
});
}
@Transactional(rollbackFor = Exception.class)
public void testTrans(long id) {
CommoditySkuActivityStock stock = stockRepository.findOne(id);
if (stock.getStock() <= 0) {
throw new ChdIgnorableException("库存不足");
}
stockRepository.save(stock);
}