库存扣减、创建订单,如何拆成TCC?
典型回答 这是一个比较典型的场景题,考察对TCC的理解。 我们先来回顾一下TCC。 ✅什么是TCC,和2PC有什么区别? 所谓TCC,就是把一个操作拆分成Try\Confirm\Cancel三个步骤,并且这三个动作已经不是一个事务了,而是三个不同的事务。 怎么理解上面这句话呢? Try\Confirm\Cancel分别是三个不同的方法,站在事务参与者的角度,在代码中,每一次调用Try或者Confirm或者Cancel的时候,都会单独开启一个数据库事务(如果数据库支持的话),这就是2PC比较大的区别,2PC从头到尾就一个事务。 那么TCC如何拆呢?其实再看下TCC的定义: Try阶段:执行业务检查,预留资源 Confirm阶段:若所有Try成功,提交资源 Cancel阶段:若任一Try失败,释放预留资源 那么回到问题上,针对库存扣减,如何拆解成TCC呢? Try阶段:执行业务检查,预留资源 冻结库存 <font style="color:rgb(64, 64, 64);">update inventory_table set frozen_inventory = frozen_inventory + #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">冻结库存</font> + 1,用户看到的<font style="color:rgb(64, 64, 64);">可用库存</font> = <font style="color:rgb(64, 64, 64);">剩余库存</font> - <font style="color:rgb(64, 64, 64);">冻结库存</font> ,那么,这就起到了资源预留的作用。 Confirm阶段:若所有Try成功,提交资源 解冻并扣减库存 <font style="color:rgb(64, 64, 64);">update inventory_table set frozen_inventory = frozen_inventory - #{count},saleable_inventory = saleable_inventory - #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">冻结库存</font> - 1, <font style="color:rgb(64, 64, 64);">剩余库存</font> - 1,即真正做库存扣减。 Cancel阶段:若任一Try/Confirm失败,释放预留资源 解冻库存 <font style="color:rgb(64, 64, 64);">update inventory_table set frozen_inventory = frozen_inventory - #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">冻结库存</font> - 1, 即释预留资源 Cancel阶段:若Confirm成功,但是其他参与者失败,需要回滚Confirm操作 回退库存 <font style="color:rgb(64, 64, 64);">update inventory_table set saleable_inventory = saleable_inventory + #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">剩余库存</font> + 1,即回退库存扣减操作。 ...