面试题答案
一键面试常见分布式事务解决方案
- XA协议
- 原理:XA协议是一种基于两阶段提交(2PC)的分布式事务协议。在第一阶段(准备阶段),所有参与事务的资源管理器准备提交,向事务协调者汇报准备情况;第二阶段(提交阶段),事务协调者根据所有资源管理器的准备情况决定是提交还是回滚事务,如果所有资源管理器都准备成功则提交,否则回滚。
- 优点:严格遵循ACID原则,能保证强一致性。
- 缺点:性能开销大,长时间锁定资源,可能导致资源争用和死锁,对网络故障敏感。
- TCC模式(Try - Confirm - Cancel)
- 原理:TCC模式将事务分成三个阶段。Try阶段主要是对业务资源进行检测和预留;Confirm阶段在Try成功后,对预留的资源进行正式操作;Cancel阶段在Try阶段失败时,对Try阶段预留的资源进行释放。
- 优点:性能较好,对资源锁定时间短。
- 缺点:实现复杂,业务侵入性强,每个服务都需要实现Try、Confirm和Cancel三个接口。
- Saga模式
- 原理:Saga模式将一个长事务分解为多个本地短事务,每个本地事务都有对应的补偿事务。当其中某个本地事务失败时,会按照顺序调用之前已成功事务的补偿事务进行回滚。
- 优点:性能较好,没有长时间的资源锁定,适用于业务流程长且复杂的场景。
- 缺点:一致性较弱,是最终一致性,并且补偿逻辑实现复杂。
在Spring Boot微服务项目中应用Saga模式保证数据一致性
- 引入依赖
在Spring Boot项目的
pom.xml
中引入相关依赖,例如使用spring - cloud - sleuth
来实现分布式链路追踪,帮助定位事务执行过程中的问题,以及引入消息队列相关依赖(如spring - boot - starter - rabbitmq
)用于实现异步消息传递,以驱动Saga事务流程。<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring - cloud - sleuth - starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring - boot - starter - rabbitmq</artifactId> </dependency>
- 定义Saga事务步骤和补偿逻辑
以一个简单的电商下单、扣库存、更新订单状态的业务场景为例。
- 下单服务:
@Service public class OrderService { @Autowired private OrderRepository orderRepository; @Autowired private RabbitTemplate rabbitTemplate; public void createOrder(Order order) { // 下单逻辑 Order savedOrder = orderRepository.save(order); // 发送消息通知扣库存服务 rabbitTemplate.convertAndSend("saga - exchange", "stock - reduce", savedOrder.getId()); } public void cancelOrder(Long orderId) { // 取消订单逻辑,比如删除订单记录 orderRepository.deleteById(orderId); } }
- 扣库存服务:
@Service public class StockService { @Autowired private StockRepository stockRepository; @Autowired private RabbitTemplate rabbitTemplate; @RabbitListener(queues = "stock - reduce") public void reduceStock(Long orderId) { // 根据订单ID获取商品信息并扣库存 Stock stock = stockRepository.findByOrderId(orderId); if (stock!= null) { stock.setQuantity(stock.getQuantity() - 1); stockRepository.save(stock); // 发送消息通知更新订单状态服务 rabbitTemplate.convertAndSend("saga - exchange", "order - status - update", orderId); } else { // 库存不足,发送回滚消息 rabbitTemplate.convertAndSend("saga - exchange", "order - cancel", orderId); } } public void restoreStock(Long orderId) { // 恢复库存逻辑 Stock stock = stockRepository.findByOrderId(orderId); if (stock!= null) { stock.setQuantity(stock.getQuantity() + 1); stockRepository.save(stock); } } }
- 更新订单状态服务:
@Service public class OrderStatusService { @Autowired private OrderRepository orderRepository; @RabbitListener(queues = "order - status - update") public void updateOrderStatus(Long orderId) { // 根据订单ID更新订单状态为已下单 Order order = orderRepository.findById(orderId).orElse(null); if (order!= null) { order.setStatus("已下单"); orderRepository.save(order); } } }
- 下单服务:
- 配置消息队列和Saga事务协调
- 配置RabbitMQ:在
application.yml
中配置RabbitMQ相关信息。spring: rabbitmq: host: localhost port: 5672 username: guest password: guest
- 定义Saga事务协调逻辑:通过消息监听和发送机制,实现Saga事务的流程控制和回滚机制。例如,在扣库存服务中,如果库存不足,发送回滚消息给下单服务进行订单取消和库存恢复。 通过以上步骤,在Spring Boot微服务项目中实现了Saga模式来保证分布式事务的数据一致性。
- 配置RabbitMQ:在