Spring Boot 分布式事务高阶玩法:从入门到精通

嘿,各位 Java 小伙伴们!今天咱们要来聊聊 Spring Boot 里一个超酷炫但又有点让人头疼的家伙 ------ 分布式事务。这玩意儿就像是一场大型派对的组织者,要确保派对上所有的活动(操作)要么都顺顺利利地进行,要么就一起取消,绝对不能出现有的活动进行了一半,有的却没开始的尴尬局面。

为啥要有分布式事务

在以前那种单体应用的小世界里,事务处理就像在自己家里整理东西,所有的东西(数据)都在一个地方,要保证操作的一致性很容易。但随着业务越来越复杂,应用变成了分布式的 "大杂烩",各个服务就像住在不同房子里的小伙伴,这时候再想保证所有操作都一致,就需要分布式事务这个 "超级协调员" 出场啦。

Spring Boot 里的分布式事务支持

Spring Boot 对分布式事务的支持就像是给你配备了一套超级工具包。其中,@Transactional注解大家肯定都很熟悉,在单体应用里它就是事务管理的小能手。但在分布式场景下,我们还有更厉害的武器,比如基于 XA 协议的分布式事务管理器,以及像 Seata 这样的开源框架。

XA 协议的分布式事务管理器

XA 协议就像是一个国际通用的 "交流规则",它规定了数据库和事务管理器之间怎么沟通。在 Spring Boot 里使用 XA 协议的分布式事务管理器,就像是给各个服务的数据库都请了一个翻译,让它们能准确地交流事务相关的信息。

下面我们来看一段简单的代码示例,假设我们有两个服务,一个是订单服务,一个是库存服务,我们要在创建订单的同时扣减库存,并且保证这两个操作要么都成功,要么都失败。

首先,我们需要配置 XA 数据源,这里以 MySQL 为例:

kotlin 复制代码
@Configuration
public class XADataSourceConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }
    @Bean
    public DataSource dataSource() {
        return dataSourceProperties().initializeDataSourceBuilder()
              .type(com.mysql.cj.jdbc.MysqlXADataSource.class)
              .build();
    }
}

然后,配置事务管理器:

java 复制代码
@Configuration
public class XATransactionConfig {
    @Autowired
    private DataSource dataSource;
    @Bean
    public PlatformTransactionManager transactionManager() throws SQLException {
        return new JtaTransactionManager(new UserTransactionFactory(), new TransactionManagerFactory(dataSource));
    }
}

接下来,在业务代码里使用@Transactional注解:

scss 复制代码
@Service
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private StockService stockService;
    @Transactional
    public void createOrder(Order order) {
        orderRepository.save(order);
        stockService.decreaseStock(order.getProductId(), order.getQuantity());
    }
}

在这个例子里,createOrder方法上的@Transactional注解就像一个 "指挥官",它会协调订单保存和库存扣减这两个操作,确保它们在同一个事务里执行。

Seata 框架

Seata 就像是一个更智能、更强大的 "事务指挥官"。它有三个重要的组件:TC(Transaction Coordinator)事务协调器、TM(Transaction Manager)事务管理器和 RM(Resource Manager)资源管理器。TC 就像一个调度中心,TM 负责发起和管理事务,RM 则负责管理资源和提交 / 回滚事务。

使用 Seata,我们首先要在项目里引入相关依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

然后,配置 Seata 客户端:

yaml 复制代码
seata:
  application-id: ${spring.application.name}
  tx-service-group: my_test_tx_group
  enable-auto-data-source-proxy: true
  client:
    rm:
      async-commit-buffer-limit: 10000
      lock:
        retry-interval: 10
        retry-times: 30
        retry-policy-branch-rollback-on-conflict: true
    tm:
      commit-retry-count: 5
      rollback-retry-count: 5
    undo:
      data-validation: true
      log-serialization: jackson
      log-table: undo_log

在业务代码里,我们使用@GlobalTransactional注解来开启全局事务:

scss 复制代码
@Service
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private StockService stockService;
    @GlobalTransactional
    public void createOrder(Order order) {
        orderRepository.save(order);
        stockService.decreaseStock(order.getProductId(), order.getQuantity());
    }
}

这里的@GlobalTransactional注解就像是给整个分布式事务场景下了一道 "圣旨",让所有涉及到的服务都按照统一的事务规则来执行。

总结

分布式事务虽然复杂,但有了 Spring Boot 提供的强大支持,以及像 Seata 这样优秀的框架,我们也能轻松应对。就像掌握了一门高超的魔法,让我们的分布式系统变得更加可靠和强大。希望今天的分享能让大家对 Spring Boot 中的分布式事务有更深入的理解,在开发的道路上一路 "开挂",解决各种复杂的业务场景。

相关推荐
forestsea几秒前
Java并发编程面试题:锁(17题)
java·开发语言
顾言4 分钟前
Java 线程中断 Interrupted
java·后端
小杨4046 分钟前
springboot框架项目实践应用二十(扩展mybatis插件及原理解析)
spring boot·后端·mybatis
红云梦10 分钟前
高并发三剑客-本地缓存之王Caffeine-01缓存应用
java·redis·缓存
MacroZheng11 分钟前
狂揽77k star!GitHub官方支持的画图神器,用起来够优雅!
java·spring boot·后端
爱的叹息22 分钟前
关于 Spring Boot 监控方式的详细对比说明及总结表格
java·spring boot·后端
李少兄36 分钟前
【Java基础】Java集合遍历方式
java·开发语言·windows
DreamBoat_Onism37 分钟前
JVM 概述
java·jvm·后端
努力的搬砖人.38 分钟前
Spring Boot整合Kafka的详细步骤
spring boot·后端·kafka
络740 分钟前
分布式应用架构的演变
java·分布式·架构