黑马商城 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]