设计思路
- 基于XA协议:使用支持XA协议的数据库,如MySQL 5.7+ 。在订单创建、库存扣减和支付等微服务涉及的数据库操作时,通过XA事务管理器来协调各个数据库资源。但这种方式性能较低,因为事务执行过程中会锁定资源直到整个事务完成。
- TCC(Try - Confirm - Cancel)模式:
- Try阶段:各个微服务尝试预留资源,比如订单微服务创建预订单,库存微服务预扣减库存,支付微服务预冻结支付金额。
- Confirm阶段:当所有Try操作成功后,各个微服务执行真正的提交操作,完成订单创建、库存扣减和支付。
- Cancel阶段:如果Try阶段有任何一个操作失败,已执行Try操作的微服务进行回滚,释放预留资源。
- Saga模式:
- 将一个长事务分解为多个本地事务,每个本地事务对应一个微服务操作。
- 通过事件驱动的方式来协调各个微服务。例如,订单创建成功后发送一个事件,库存微服务监听该事件并执行库存扣减,库存扣减成功再发送事件通知支付微服务进行支付。
- 当某个步骤失败时,通过补偿事务来恢复数据一致性,比如库存扣减失败,订单微服务执行取消订单操作。
关键代码实现点
- 基于XA协议(以Spring Boot + MySQL为例):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql - connector - java</artifactId>
</dependency>
- **配置数据源**:
@Bean
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSourceProperties masterDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
public DataSource masterDataSource() {
return masterDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(10000);
return userTransactionImp;
}
@Bean
public AtomikosDataSourceBean masterXADataSource() throws SQLException {
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
xaDataSource.setUniqueResourceName("masterXA");
xaDataSource.setXAProperties(masterDataSourceProperties().getProperties());
return xaDataSource;
}
- **使用事务管理器**:
@Configuration
@EnableTransactionManagement
public class TransactionConfig {
@Bean
public PlatformTransactionManager transactionManager() throws Throwable {
UserTransaction userTransaction = userTransaction();
TransactionManager transactionManager = new AtomikosTransactionManager();
transactionManager.setUserTransaction(userTransaction);
return new JtaTransactionManager(userTransaction, transactionManager);
}
}
- **在服务层使用事务**:
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Transactional
public void createOrder(Order order) {
orderRepository.save(order);
// 调用库存和支付服务,XA事务会自动管理
}
}
- TCC模式(以Hmily框架为例):
<dependency>
<groupId>org.dromara</groupId>
<artifactId>hmily - spring - boot - starter</artifactId>
<version>1.5.2</version>
</dependency>
- **定义Try、Confirm、Cancel方法**:
@Service
public class OrderTccService {
@HmilyTCC(confirmMethod = "confirmCreateOrder", cancelMethod = "cancelCreateOrder")
public void tryCreateOrder(Order order) {
// 创建预订单逻辑
}
public void confirmCreateOrder(Order order) {
// 确认订单创建逻辑
}
public void cancelCreateOrder(Order order) {
// 取消订单创建逻辑
}
}
- Saga模式(以Spring Cloud Stream + Eventuate Tram为例):
<dependency>
<groupId>io.eventuate.tram</groupId>
<artifactId>eventuate - tram - spring - cloud - stream - starter</artifactId>
<version>0.12.0.RELEASE</version>
</dependency>
- **定义事件和事件处理器**:
@Service
public class OrderEventHandler {
@Autowired
private OrderRepository orderRepository;
@StreamListener(TramEventsDefinition.EVENT_IN)
@TramEventHandler
public void handleOrderCreatedEvent(OrderCreatedEvent event) {
Order order = orderRepository.findById(event.getOrderId()).orElse(null);
if (order!= null) {
// 处理订单创建事件,如发送库存扣减事件
}
}
}
- **发送事件**:
@Service
public class OrderService {
@Autowired
private TramEventPublisher tramEventPublisher;
public void createOrder(Order order) {
orderRepository.save(order);
OrderCreatedEvent event = new OrderCreatedEvent(order.getId());
tramEventPublisher.publish(TramEventsDefinition.EVENT_OUT, event);
}
}