在一家做公司内部系统待了一年,不是互联网公司,都是单机系统,并发的思想快忘记和麻木了,代码写的越来越不严谨,导致今天出现一个并发bug,特写个笔记避免忘记思路,代码都是伪代码,但不影响查看,handle()方法为查看入口。
特别说明:网上也有乐观锁的例子,但是都是事务内重复查询,这可能导致查询的是同一笔数据,无法达到预期效果,应改为在非事务方法重复查询解决。
Stock库存表
字段:id主键,num库存数量
Order订单表
字段:略
//该方法开始查看
void handle(){
while(true){//自旋
Stock stock="select * from Stock where id=1";//注意:因为mysql MVCC原理,必须非事务方法查询,否则可能每次查询的数据都是同一笔。
if(stock.getNum==0){
"抛异常报库存不够"
}
if(handleBiz(stock.getNum)){
return;
}
}
}
@Transactional
boolean handleBiz(preStockNum){
if(updateStock(preStockNum)){
createOrder();
return true;
}
return false;
}
boolean updateStock(preStockNum){
int count = "update Stock set num=num-1 where id=1 and num='preStockNum'";
if(count>1){
return true;
}
return false;
}
void createOrder(){
"insert Order (...) values (...)";
}