文章目录
- 一、直接用更新的sql实现
- 1. 场景描述
- 2. 修改sql
- StockMapper
- StockService
- 3. 重新测试
- 二、问题
- 1. 锁范围问题:行级锁 表级锁
- 2. 若逻辑太复杂,一个sql无法实现
- 4. 无法监控库存变化前后的状态
一、直接用更新的sql实现
1. 场景描述
之前的deduct()方法中,
先查询count
判断条件满足后count-1
最后update
那么如果直接将它修改成一条sql语句呢
update db_stock set count = count-1 where product_code = ‘1001’ and count >= 1
2. 修改sql
StockMapper
@Mapper
public interface StockMapper extends BaseMapper<Stock> {
@Update("update db_stock set count = count-#{count} where product_code = #{productCode} and count >= #{count} ")
int updateCount(@Param("productCode") String productCode, @Param("count") Integer count);
}
StockService
@Service
public class StockService {
@Autowired
private StockMapper stockMapper;
private ReentrantLock lock = new ReentrantLock();
public void deduct() {
stockMapper.updateCount("1001", 1);
}
}
3. 重新测试
还是用之前的集群部署来测试,看是否解决问题。
吞吐量大大提升,311。
再看数据库,成功清0,问题解决,保证了线程安全
二、问题
1. 锁范围问题:行级锁 表级锁
可参考mysql锁范围:表级锁和行级锁