高级篇:分布式事务-Seata

148 阅读1分钟

分布式事务

  • CAP 理论
  • BASE 理论
    • Basically Available (基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用
    • Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。
    • Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。

Seata

seata简介

  • 角色

image.png

  • Seata提供了四种不同的分布式事务解决方案:
    • XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入

    • TCC模式:最终一致的分阶段事务模式,有业务侵入

    • AT模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式

    • SAGA模式:长事务模式,有业务侵入

Seata 中TC服务器的部署:

Seata TCC

image.png

幂等性解决 && 空回滚的处理

image.png commit不需要处理幂等问题,应为commit是业务删除,幂等也无所谓

业务悬挂的解决

image.png


@Slf4j
public class AccountTCCServiceImpl implements AccountTCCService {

    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private AccountFreezeMapper freezeMapper;

    @Override
    @Transactional
    public void deduct(String userId, int money) {
        // 0.获取事务id
        String xid = RootContext.getXID();
        // 1.扣减可用余额
        accountMapper.deduct(userId, money);
        // 2.记录冻结金额,事务状态
        AccountFreeze freeze = new AccountFreeze();
        freeze.setUserId(userId);
        freeze.setFreezeMoney(money);
        freeze.setState(AccountFreeze.State.TRY);
        freeze.setXid(xid);
        freezeMapper.insert(freeze);
    }

    @Override
    public boolean confirm(BusinessActionContext ctx) {
        // 1.获取事务id
        String xid = ctx.getXid();
        // 2.根据id删除冻结记录
        int count = freezeMapper.deleteById(xid);
        return count == 1;
    }

    @Override
    public boolean cancel(BusinessActionContext ctx) {
        // 0.查询冻结记录
        String xid = ctx.getXid();
        AccountFreeze freeze = freezeMapper.selectById(xid);

        // 1.恢复可用余额
        accountMapper.refund(freeze.getUserId(), freeze.getFreezeMoney());
        // 2.将冻结金额清零,状态改为CANCEL
        freeze.setFreezeMoney(0);
        freeze.setState(AccountFreeze.State.CANCEL);
        int count = freezeMapper.updateById(freeze);
        return count == 1;
    }
}

附录

seata中四种模式的分析

image.png