Seata
Seata是一个开源的分布式事务解决方案,它提供了高性能和简单易用的API。Seata支持AT模式、TCC模式、SAGA模式和XA模式。
| 特性 | AT | TCC | SAGA | XA(2PC)) | 消息 |
|---|---|---|---|---|---|
| 一致性 | 最终一致性AP | 最终一致性AP | 最终一致性AP | CP强一致性 | 最终一致性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 环境,