杀鸡焉用牛刀 发表于 2025-3-17 04:16:57

黑马商城 Spring Cloud 微服务课程条记:分布式事务 - Seata 的架构和原理

目次
黑马商城 Spring Cloud 微服务课程条记:分布式事务 - Seata 的架构和原理
一、Seata 解决的问题场景
二、Seata 的架构
三、Seata 的原理


在黑马商城的微服务架构中,当涉及到多个微服务协同完成一个业务操作时,分布式事务的处置惩罚变得至关重要。此中,Seata 是一个开源的分布式事务解决方案,用于解决微服务架构中的分布式事务问题。
一、Seata 解决的问题场景


在黑马商城中,比方用户下单购买商品这个业务场景,涉及到订单服务创建订单、库存服务扣减库存、用户服务扣除积分等多个微服务操作。如果这些操作不能保证在一个事务内执行,就大概出现部门操作乐成、部门操作失败的情况,导致数据不一致。Seata 就是为了解决这种分布式事务场景下的数据一致性问题。
二、Seata 的架构



[*]TC(Transaction Coordinator)- 事务协调者

[*]负责协调和管理全局事务,是全局事务的核心管理者。它接收事务发起者的哀求,协调各个加入者的事务执行,决定事务是提交还是回滚。
[*]代码示例(伪代码,实际 Seata TC 是独立部署的服务,这里只是示意其协调逻辑):


public class TransactionCoordinator {
    private List<TransactionParticipant> participants;

    public TransactionCoordinator(List<TransactionParticipant> participants) {
      this.participants = participants;
    }

    public void handleTransaction() {
      // 向参与者发送准备请求
      for (TransactionParticipant participant : participants) {
            participant.prepare();
      }
      // 收集参与者的准备结果
      boolean allPrepared = true;
      for (TransactionParticipant participant : participants) {
            if (!participant.isPrepared()) {
                allPrepared = false;
                break;
            }
      }
      if (allPrepared) {
            // 所有参与者准备成功,发送提交请求
            for (TransactionParticipant participant : participants) {
                participant.commit();
            }
      } else {
            // 有参与者准备失败,发送回滚请求
            for (TransactionParticipant participant : participants) {
                participant.rollback();
            }
      }
    }
}


[*]TM(Transaction Manager)- 事务管理器

[*]定义全局事务的范围,开始全局事务、提交或回滚全局事务。它与业务逻辑精密联合,负责将业务操作纳入到分布式事务管理中。
[*]代码示例(伪代码,假设在订单服务中利用):


import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
    @GlobalTransactional
    public void createOrder() {
      // 业务逻辑,创建订单,调用其他服务等
      // 这里的方法执行就会被Seata的TM纳入到全局事务管理中
    }
}


[*]RM(Resource Manager)- 资源管理器

[*]管理分支事务的资源,如数据库毗连等。它负责向 TC 注册分支事务,报告分支事务的状态,并根据 TC 的指令执行当地事务的提交或回滚。
[*]以数据库为例,假设在库存服务中利用 Seata 管理数据库事务(伪代码):


import javax.sql.DataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SeataDataSourceConfig {
    @Bean
    public DataSource dataSource() {
      // 假设这里获取到了实际的数据源,比如DruidDataSource等
      DataSource actualDataSource = // 获取实际数据源的代码
      return new DataSourceProxy(actualDataSource);
    }
}
三、Seata 的原理



[*]一阶段(执行当地事务并注册分支事务)

[*]当业务操作开始时,TM 向 TC 发起全局事务开始哀求,TC 生成全局事务 ID 并返回给 TM。
[*]各个微服务(RM)执行当地事务,在执行当地事务前,RM 会向 TC 注册分支事务,将自己纳入到全局事务管理中。
[*]当地事务执行完成后,RM 会向 TC 报告当地事务的执行状态(乐成或失败)。
[*]代码示例(联合前面的订单、库存服务示例,假设库存服务执行当地事务并注册分支事务):


import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.api.TransactionalExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class StockService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GlobalTransactional
    public void deductStock() {
      // 获取全局事务ID
      String xid = RootContext.getXID();
      try {
            // 执行本地事务,扣减库存
            jdbcTemplate.update("UPDATE stock SET quantity = quantity - 1 WHERE product_id =?", 1);
            // 向TC注册分支事务,这里假设已经有相关的Seata客户端配置
            TransactionalExecutor.registerBranchTransaction(xid, "库存服务", null);
      } catch (Exception e) {
            // 如果本地事务执行失败,向TC报告失败状态,这里简化处理,实际可能需要更完善的错误处理
            TransactionalExecutor.reportFailure(xid, e);
            throw e;
      }
    }
}


[*]二阶段(提交或回滚全局事务)

[*]提交阶段

[*]如果所有分支事务的一阶段都执行乐成并且向 TC 报告了乐成状态,TC 会向所有 RM 发送提交哀求。
[*]RM 收到提交哀求后,提交当地事务。

[*]回滚阶段

[*]如果有任何一个分支事务在一阶段执行失败或者向 TC 报告了失败状态,TC 会向所有 RM 发送回滚哀求。
[*]RM 收到回滚哀求后,根据一阶段记载的 undo 日志进行回滚操作,将数据恢复到事务开始前的状态。

[*]代码示例(Seata 的二阶段提交和回滚操作是由 Seata 框架自动处置惩罚的,这里无法给出详细的代码实现,但可以简单示意回滚逻辑的思路,假设在库存服务中处置惩罚回滚):


import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.api.TransactionalExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class StockService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GlobalTransactional
    public void deductStock() {
      String xid = RootContext.getXID();
      try {
            // 执行本地事务,扣减库存
            jdbcTemplate.update("UPDATE stock SET quantity = quantity - 1 WHERE product_id =?", 1);
            // 向TC注册分支事务等操作(前面已示例)
      } catch (Exception e) {
            // 如果本地事务执行失败,向TC报告失败状态(前面已示例)
            // 假设这里收到TC的回滚请求后,进行回滚操作
            if (TransactionalExecutor.isRollbackOnly(xid)) {
                // 根据undo日志进行回滚,这里简化为直接增加库存(实际需要根据undo日志正确恢复数据)
                jdbcTemplate.update("UPDATE stock SET quantity = quantity + 1 WHERE product_id =?", 1);
            }
            throw e;
      }
    }
}

Seata 通过其独特的架构和事务处置惩罚原理,为黑马商城的微服务架构提供了有效的分布式事务解决方案,确保在复杂的微服务协作场景下数据的一致性。在实际应用中,需要根据具体的业务需求和技能架构公道配置和利用 Seata。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 黑马商城 Spring Cloud 微服务课程条记:分布式事务 - Seata 的架构和原理