Seata

Seata是一个开源的分布式事务解决方案,它提供了高性能和简单易用的API。Seata支持AT模式、TCC模式、SAGA模式和XA模式。

特性ATTCCSAGAXA(2PC))消息
一致性最终一致性AP最终一致性AP最终一致性APCP强一致性最终一致性AP
侵入性
性能
复杂度简单复杂中等简单中等
使用场景常规业务金融交易长流程/跨系统强一致性核心系统异步解耦、非核心链路

例如电商订单系统中,库存扣减用 AT 模式,支付用 TCC 模式,物流用 SAGA 模式,积分发放、日志同步使用消息

CAP理论

一致性(Consistency)、可用性(Availability)、分区容忍性(Partition Tolerance)

在保证分区容忍性的前提下一致性和可用性无法兼顾,如果要提高系统的可用性就要增加多个结点,如果要保证数据的一致性就要实现每个结点的数据一致,结点越多可用性越好,但是数据一致性越差。所以,在进行分布式系统设计时,同时满足“一致性”、“可用性”和“分区容忍性”三者是几乎不可能的

CAP有哪些组合方式?

1、CA:放弃分区容忍性,加强一致性和可用性,关系数据库按照CA进行设计。

2、AP:放弃一致性,加强可用性和分区容忍性,追求最终一致性,很多NoSQL数据库按照AP进行设计。

说明:这里放弃一致性是指放弃强一致性,强一致性就是写入成功立刻要查询出最新数据。追求最终一致性是指允许暂时的数据不一致,只要最终在用户接受的时间内数据 一致即可

3、CP:放弃可用性,加强一致性和分区容忍性,一些强一致性要求的系统按CP进行设计,比如跨行转账,一次转账请求要等待双方银行系统都完成整个事务才算完成。

总结: 在分布式系统设计中AP的应用较多,即保证分区容忍性和可用性,牺牲数据的强一致性(写操作后立刻读取到最新数据),保证数据最终一致性。比如:订单退款,今日退款成功,明日账户到账,只要在预定的用户可以接受的时间内退款事务走完即可。

** 使用示例(TCC)**

1、引用类库

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>版本号</version>
</dependency>

2、配置 Seata

seata:
  enabled: true
  application-id: 应用ID
  tx-service-group: tx-group-name
  client:
    rm:
      async-commit-buffer-limit: 10000
      report-retry-count: 5
      table-meta-check-enable: false
      report-success-enable: false
    tm:
      commit-retry-count: 5
      rollback-retry-count: 5
  service:
    vgroup-mapping:
      tx-group-name: default
    grouplist:
      default: 127.0.0.1:8091

3、编写业务类

import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;

@LocalTCC
public class AccountTCCService {
    @TwoPhaseBusinessAction(name = "debit", commitMethod = "confirmDebit", rollbackMethod = "cancelDebit")
    public void debit(@BusinessActionContextParameter(paramName = "userId") String userId, 
                      @BusinessActionContextParameter(paramName = "amount") BigDecimal amount, 
                      BusinessActionContext actionContext) {
        // Try 阶段逻辑,例如检查余额并预留资源等。
    }
    
    public void confirmDebit(BusinessActionContext ctx) {
        // Confirm 阶段逻辑,例如真正扣减余额等。需要保证幂等性。
    }
    
    public void cancelDebit(BusinessActionContext ctx) {
        // Cancel 阶段逻辑,例如释放资源等。需要保证幂等性。
    }
}

4、使用TCC服务类进行事务管理

import io.seata.core.context.RootContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.transaction.Transactional; // Java EE 方式的事务管理注解,与 Spring 的 @Transactional 不冲突,但要确保事务管理器正确配置为 JTA 或 Spring 的 TransactionManager。
import java.math.BigDecimal;

@Service
public class TransactionalService {
    @Autowired
    private AccountTCCService accountTCCService; // 自动注入上面定义的 TCC 服务类。
    @Autowired // 如果使用 Spring 的事务管理器,则使用 @Transactional。如果是 JTA,则使用 @javax.transaction.Transactional。确保事务管理器配置正确。这里用的是 Spring 的方式。
    @Transactional(rollbackFor = Exception.class) // 使用 Spring 的事务管理注解。如果是 JTA 环境,