使用Seata XA模式的全局事务管理在SpringCloud电商订单系统中的应用

在开发电商系统的过程中,订单创建是一项非常关键的功能。本文将介绍如何在订单创建过程中,结合Spring Cloud和Seata的XA模式来实现全局事务管理,以确保数据的一致性和完整性。

Seata 配置

首先,我们需要配置 Seata 的数据源代理模式。这里我们选择使用 XA 模式:

seata:
  data-source-proxy-mode: XA
订单创建过程详解

在这段代码中,我们通过@GlobalTransactional注解来声明一个全局事务。以下是具体的实现步骤:

@Override
@GlobalTransactional
public Long createOrder(OrderFormDTO orderFormDTO) {
    // 1.订单数据
    Order order = new Order();
    // 1.1.查询商品
    List<OrderDetailDTO> detailDTOS = orderFormDTO.getDetails();
    // 1.2.获取商品id和数量的Map
    Map<Long, Integer> itemNumMap = detailDTOS.stream()
                                              .collect(Collectors.toMap(OrderDetailDTO::getItemId,
                                                                        OrderDetailDTO::getNum));
    Set<Long> itemIds = itemNumMap.keySet();
    // 1.3.查询商品
    List<ItemDTO> items = itemClient.queryItemByIds(itemIds);
    if (items == null || items.size() < itemIds.size()) {
        throw new BadRequestException("商品不存在");
    }
    // 1.4.基于商品价格、购买数量计算商品总价:totalFee
    int total = 0;
    for (ItemDTO item : items) {
        total += item.getPrice() * itemNumMap.get(item.getId());
    }
    order.setTotalFee(total);
    // 1.5.其它属性
    order.setPaymentType(orderFormDTO.getPaymentType());
    order.setUserId(UserContext.getUser());
    order.setStatus(1);
    // 1.6.将Order写入数据库order表中
    save(order);

    // 2.保存订单详情
    List<OrderDetail> details = buildDetails(order.getId(), items, itemNumMap);
    detailService.saveBatch(details);

    // 3.扣减库存
    try {
        itemClient.deductStock(detailDTOS);
    } catch (Exception e) {
        throw new RuntimeException("库存不足!");
    }

    // 4.清理购物车商品
    cartClient.deleteCartItemByIds(itemIds);
    return order.getId();
}
关键步骤解析
  1. 订单数据初始化

    • 创建订单对象并设置订单的基础信息。
  2. 查询商品

    • 从订单表单中获取商品详情,并根据商品ID查询商品信息。
    • 如果查询不到所有商品,则抛出异常。
  3. 计算总价

    • 根据商品的价格和购买数量计算订单的总金额。
  4. 写入数据库

    • 将订单信息保存到数据库的订单表中。
  5. 保存订单详情

    • 构建订单详情列表并批量保存到订单详情表中。
  6. 扣减库存

    • 调用商品服务扣减库存,如果库存不足,则抛出异常。
  7. 清理购物车

    • 删除购物车中已下单的商品。
XA模式的优势

XA模式是一种分布式事务协议,用于确保多个资源管理器之间的数据一致性。使用Seata的XA模式,可以在分布式系统中实现强一致性的事务处理,尤其适用于需要跨多个数据库或服务的复杂场景。在本例中,使用XA模式可以确保订单创建、库存扣减和购物车清理这些操作在一个全局事务中完成,避免因部分操作失败而导致的数据不一致问题。

XA模式的缺点

尽管XA模式在确保数据一致性方面有显著优势,但也存在一些缺点:

事务锁竞争

  • 在XA事务中,资源锁的持有时间较长,可能导致数据库锁竞争加剧,影响系统的并发性能。

通过Spring Cloud与Seata XA模式的结合,我们能够在分布式架构下高效地管理全局事务,提升系统的可靠性和数据一致性,同时也需要权衡其带来的复杂性和性能开销。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba使用Seata进行分布式事务,需要进行以下步骤: 1. 引入Seata依赖 在pom.xml文件引入Seata的依赖: ``` <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <version>2.2.0.RELEASE</version> </dependency> ``` 2. 配置Seata 在application.yml文件配置Seata的相关参数,包括: - 服务端配置 ``` spring: cloud: alibaba: seata: tx-service-group: my_test_tx_group # Seata事务组名称 service: vgroup-mapping: my_test_tx_group: default # Seata服务组名称 group-id: default # Seata服务分组ID config: type: file # Seata配置类型 file: name: file.conf # Seata配置文件名称 path: /seata/config # Seata配置文件路径 ``` - 客户端配置 ``` mybatis: configuration: # 启用二级缓存 cache-enabled: true # 数据源配置 type-aliases-package: com.example.demo.entity mapper-locations: classpath:mapper/*.xml configuration-properties: # 自动驼峰转换 mapUnderscoreToCamelCase: true # 数据库连接池配置 druid: url: jdbc:mysql://localhost:3306/seata?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver # Seata配置 seata: enabled: true # 启用Seata application-id: seata-demo # 应用ID tx-service-group: my_test_tx_group # Seata事务组名称 service: vgroup-mapping: my_test_tx_group: default # Seata服务组名称 # 注册心配置 registry: type: nacos # 注册心类型 nacos: server-addr: localhost:8848 # 注册心地址 namespace: public group: SEATA_GROUP file: name: file.conf # 注册心配置文件名称 path: /seata/config # 注册心配置文件路径 ``` 3. 配置数据源 在application.yml文件配置数据源,包括: ``` spring: datasource: url: jdbc:mysql://localhost:3306/seata?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver ``` 4. 配置Seata代理数据源 在Spring Boot启动类配置Seata代理数据源: ``` @SpringBootApplication @EnableDiscoveryClient @MapperScan("com.example.demo.mapper") @EnableFeignClients(basePackages = "com.example.demo.feign") @EnableTransactionManagement public class SeataDemoApplication { public static void main(String[] args) { SpringApplication.run(SeataDemoApplication.class, args); } @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { return new DruidDataSource(); } @Bean public DataSourceProxy dataSourceProxy(DataSource dataSource) { return new DataSourceProxy(dataSource); } @Bean public GlobalTransactionScanner globalTransactionScanner() { return new GlobalTransactionScanner("seata-demo", "my_test_tx_group"); } } ``` 5. 编写业务代码 在业务代码使用@GlobalTransactional注解标记需要参与分布式事务的方法,例如: ``` @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired private OrderFeignClient orderFeignClient; @Override @GlobalTransactional public void createOrder(User user) { userMapper.insert(user); orderFeignClient.createOrder(user.getId()); } } ``` 以上就是在Spring Cloud Alibaba使用Seata进行分布式事务的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值