MST

星途 面试题库

面试题:微服务架构基于Spring Cloud实现高效服务调用时的分布式事务处理

在基于Spring Cloud构建的微服务架构进行高效服务调用过程中,不可避免会遇到分布式事务问题。请详细阐述如何结合Spring Cloud Alibaba的Seata等框架解决分布式事务,包括Seata的工作原理、模式(如AT、TCC等)以及如何在项目中进行配置和优化,以保证数据一致性和服务调用的高效性。
30.6万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

Seata工作原理

  1. 整体架构:Seata 由三个核心组件组成,分别是 Transaction Coordinator (TC)、Transaction Manager (TM) 和 Resource Manager (RM)。
    • TC:事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
    • TM:事务管理器,定义全局事务的范围,开始全局事务、提交或回滚全局事务。
    • RM:资源管理器,管理分支事务处理的资源,与TC 进行通信,汇报分支事务的状态,驱动分支事务的提交或回滚。
  2. 事务处理流程
    • 全局事务开启:TM 向 TC 申请开启一个全局事务,TC 会为该全局事务生成一个全局唯一的 XID。
    • 分支事务注册:RM 参与到全局事务中,向 TC 注册分支事务,并将其纳入到该全局事务的管辖之下。
    • 事务执行:各个 RM 执行分支事务,并向 TC 汇报事务状态。
    • 全局事务结束:TM 根据所有分支事务的执行结果决定全局事务是提交还是回滚。如果所有分支事务都成功,TC 协调所有 RM 提交分支事务;如果有任何一个分支事务失败,TC 协调所有 RM 回滚分支事务。

Seata模式

  1. AT模式(自动补偿模式)
    • 原理
      • 一阶段:在业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
      • 二阶段 - 提交:因为一阶段本地事务已经提交,所以二阶段提交是一个空操作。
      • 二阶段 - 回滚:通过回滚日志,反向执行一阶段的操作,恢复数据到事务开始前的状态。
    • 优点:对业务侵入性低,只需关注业务 SQL,几乎不需要额外的开发工作,适合大多数场景。
    • 缺点:可能产生脏回滚(一阶段提交后二阶段回滚时,数据已经被其他事务修改),对高并发场景下的锁竞争敏感。
  2. TCC模式(Try - Confirm - Cancel模式)
    • 原理
      • Try阶段:主要是对业务系统资源进行检测和预留。
      • Confirm阶段:在 Try 成功后执行,真正执行业务操作,对 Try 阶段预留的资源进行确认使用。
      • Cancel阶段:在 Try 成功但 Confirm 失败时执行,释放 Try 阶段预留的资源。
    • 优点:适合对性能要求高,且业务场景复杂,需要对资源进行预留和控制的场景。
    • 缺点:对业务侵入性高,需要业务开发人员实现 Try、Confirm 和 Cancel 三个方法,开发成本较高。

在项目中配置Seata

  1. 引入依赖:在Spring Boot项目的pom.xml中引入Seata相关依赖,例如:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring - cloud - starter - alibaba - seata</artifactId>
</dependency>
  1. 配置文件
    • application.yml:配置Seata客户端相关属性,例如:
seata:
  tx - service - group: my_tx_group
  service:
    vgroup - mapping:
      my_tx_group: default
  • seata - server.properties(如果需要自定义Seata服务端配置):配置Seata服务端的相关参数,如存储模式、日志路径等。
  1. 初始化数据源代理:在项目中配置数据源代理,将普通数据源包装成Seata的数据源代理,以实现对数据库操作的事务管理。例如,在Spring Boot项目中,可以通过如下配置:
@Configuration
public class DataSourceAutoConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    public DataSourceAutoProxyCreator dataSourceAutoProxyCreator() {
        DataSourceAutoProxyCreator dataSourceAutoProxyCreator = new DataSourceAutoProxyCreator();
        dataSourceAutoProxyCreator.setTargetDataSources(Collections.singletonMap("dataSource", druidDataSource()));
        dataSourceAutoProxyCreator.setBeanFactory(applicationContext);
        return dataSourceAutoProxyCreator;
    }
}
  1. 开启全局事务:在需要开启全局事务的方法或类上使用@GlobalTransactional注解,例如:
@Service
public class OrderService {

    @GlobalTransactional
    public void createOrder() {
        // 业务逻辑
    }
}

优化措施

  1. 合理选择模式:根据业务场景选择合适的Seata模式,对于简单的增删改查场景优先选择AT模式,对于复杂业务且对性能要求高的场景可考虑TCC模式。
  2. 优化锁机制:在AT模式下,通过合理设置事务隔离级别、优化SQL语句,减少锁的竞争和持有时间,降低死锁风险。
  3. 性能调优
    • 配置参数调优:对Seata服务端和客户端的配置参数进行调优,如调整事务超时时间、线程池大小等,以适应业务负载。
    • 资源复用:合理复用数据库连接等资源,减少资源创建和销毁的开销。
  4. 监控与预警:搭建Seata的监控系统,实时监控事务的执行情况,对异常事务进行预警,及时发现并解决问题,保证数据一致性和服务调用的高效性。