《分布式事务之Seata》这本书中提到过:常见的TCC实现模式有两种,分别是“资源预留模式”与“补偿模式”。
TCC资源预留模式的典型就是A向B转账场景使用“冻结金额”的这种模式:
prepare:
A.balance不变 A.freeze+amount
B.balance不变 B.freeze+amount
commit:
A.balance-amount A.freeze-amount
B.balance+amount B.freeze-amount
rollback:
A.balance不变 A.freeze-amount
B.balance不变 B.freeze-amount
TCC补偿模式的例子这里借用书中的“下订单+减库存”场景:
phase 1:
order.insert() stock.deduct() & stock.record()//记录库存变化流水
phase 2.commit:
order.什么也不做 stock.deleteRecord()//删除库存变化流水
phase 2.rollback:
order.delete() stock.add()//补偿phase1减少的库存 & stock.deleteRecord()
AT模式因为有全局锁的存在,所以可以较容易的处理读写隔离问题。
而TCC的”资源预留模式“的读写隔离也比较容易理解,相当于把“变化”放到预留的资源上去执行,而平时关注的balance在全局事务为提交/回滚前是不变的,所以也实现了读写隔离(不考虑@Transactional
这种本地事务)。
但TCC的“补偿模式”是如何做到读写隔离的呢?以书上给的这个“下订单+减库存”的例子来说:tx1刚刚完成phase1但还没有进入到phase2,此时tx2也是一个全局事务,且做的动作是更新order,那不就无法做到写隔离了吗?