您当前位置:资讯中心 >开发 >浏览文章

Seata如何实现两阶段提交(2PC)分布式事务

来源:不详 日期:2024/1/26 8:18:03 阅读量:(0)

介绍

2PC,全称为两阶段提交(Two-Phase Commit),是一种在分布式系统中用来保证事务原子性和一致性的协议。它主要用于协调分布式数据库或分布式事务环境中的多个参与者,确保所有参与者要么一起成功提交事务,要么一起回滚事务,以保持数据的一致性。

图片图片

在2PC协议中有两个主要阶段:

  1. 准备阶段(Prepare Phase):

事务协调器接收到发起事务的客户端请求后,向所有参与该事务的资源管理器(例如数据库、服务节点等)发送“准备提交”请求。

每个资源管理器执行事务操作,并将事务相关的更改锁定但不提交,然后回复事务协调器它们是否准备好提交事务(根据各自是否能够成功完成事务而定)。

  1. 提交阶段(Commit Phase):
  • 如果事务协调器收到了所有资源管理器的肯定答复,即所有参与者都准备好提交事务,则向所有参与者发出“正式提交”指令。

  • 若协调器收到任何一个参与者的否定响应,或者在等待超时后仍有参与者未响应,则向所有参与者发出“回滚事务”的指令。

通过这种方式,2PC确保了所有节点要么全部完成事务,要么全部撤销事务,从而维护了分布式环境下的事务原子性。然而,2PC也存在一些缺点,比如单点故障问题(即事务协调器宕机可能导致事务长期阻塞)、网络分区情况下的不确定性以及性能上的潜在瓶颈。

Seata把一个分布式事务理解成一个包含了若干分支事务的全局事务。全局事务的职责是协调其下管辖的分支事务 达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个关系数据库的本地事务,下图是全局事务与分支事务的关系图:

图片图片

与 传统2PC 的模型类似,Seata定义了3个组件来协议分布式事务的处理过程

图片图片

  • Transaction Coordinator (TC):事务协调器,它是独立的中间件,需要独立部署运行,它维护全局事务的运行状态,接收TM指令发起全局事务的提交与回滚,负责与RM通信协调各各分支事务的提交或回滚。
  • Transaction Manager (TM):事务管理器,TM需要嵌入应用程序中工作,它负责开启一个全局事务,并最终向TC发起全局提交或全局回滚的指令。
  • Resource Manager (RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器TC的指令,驱动分支(本地)事务的提交和回滚。

具体实现

案例分析:两个账户在不同的银行(张三在bank1、李四在bank2),bank1和bank2是两个微服务。交易过程是,张三给李四转账指定金额。

上述交易步骤,要么一起成功,要么一起失败,必须是一个整体性的事务。

图片图片

为了简化环境搭建,小编这里采用file启动seata,项目搭建也只是两个普通的SpringBoot项目,未使用微服务。

下载seata服务器

官方下载地址:https://github.com/seata/seata/releases

  1. registry.type=file:

registry.type=file 其类型设置为 file 时,意味着 Seata 的服务注册中心不依赖于外部的如 Nacos、Eureka、Zookeeper 等第三方注册中心,而是使用本地文件的方式来存储和管理服务节点信息。这种模式主要用于快速测试或简单的单机部署场景,因为在这种模式下无法自动发现和管理集群环境中的其他 Seata Server 节点,不具备高可用性。

  1. config.type=file:
  • config.type=file 表示 Seata 使用本地文件作为配置源。这意味着 Seata 会从指定的本地文件中读取全局事务协调器(TC)、事务管理器(TM)和资源管理器(RM)等组件所需的配置信息,而不是通过Nacos、Apollo或其他远程配置中心获取配置。这种方式同样适用于快速验证和简单部署情况,实际生产环境中可能需要结合分布式配置中心来动态更新和管理配置。

  • seata安装初始化参考《SpringCloud Alibaba微服务实战之环境准备》,注意本次启动是采用file方式启动
  • seata启动:/bin/seata-server.bat -m file

图片图片

  • bank-1 和 bank-2启动:

图片图片

bank-1 和 bank-2服务搭建

库表建立

CREATE DATABASE `bank1` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

CREATE TABLE `account_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`account_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '户主姓名',
`account_no` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '银行卡号',
`account_password` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '帐户密码',
`account_balance` double NULL DEFAULT NULL COMMENT '帐户余额',
PRIMARY KEY (`id`) USING BTREE ) 
ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
INSERT INTO `account_info` VALUES (2, '张三的账户', '1', '', 10000);
关键字:
声明:我公司网站部分信息和资讯来自于网络,若涉及版权相关问题请致电(63937922)或在线提交留言告知,我们会第一时间屏蔽删除。
有价值
0% (0)
无价值
0% (10)

分享转发:

发表评论请先登录后发表评论。愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。