分布式事务实战基于XA规范
首先我们在docker中安装2台mysql
docker run -p 3308:3306 --name mysql3308 \
-e MYSQL_ROOT_PASSWORD=xxx \
-v /data/volume/mysql/data3308:/var/lib.mysql \
-d mysql:5.7
安装两台mysql端口号分别是3307和3308。你可以自己任意修改。
这另个仓库分别代表账户余额和红包余额。
创建表的命令:
CREATE DATABASE `xa_account` /*!40100 DEFAULT CHARACTER SET utf8 */;
use xa_account;
CREATE TABLE `capital_account` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`user_id` int(10) NOT NULL COMMENT '用户ID',
`balance_amount` decimal(10,0) DEFAULT '0' COMMENT '账户余额',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='账户信息表';
INSERT INTO `capital_account` (`id`,`user_id`,`balance_amount`) VALUES (1,1,2000);
CREATE DATABASE `xa_red_account` /*!40100 DEFAULT CHARACTER SET utf8 */;
use xa_red_account;
CREATE TABLE `red_packet_account` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`user_id` int(10) NOT NULL COMMENT '用户ID',
`balance_amount` decimal(10,0) DEFAULT '0' COMMENT '账户余额',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='红包账户信息表';
INSERT INTO `red_packet_account` (`id`,`user_id`,`balance_amount`) VALUES (1,1,800);
测试方法
执行结果:
出现这个说明我们运行已经成功。上面显示的就是TM通知数据库开始,结束,准备,提交和回滚。
什么是两阶段提交?
两阶段提交协议,简称2PC,全称是two-phase commit protocol,2PC意思就是1次事务分为2个阶段;是非常经典的强一致性、中心化的原子提交协议。
中心化是指协议中有2种角色:一个是中心协调者和N个参与者
协调者:TM事务管理器,负责协调和管理事务。
参与者:RM资源管理器,可以理解为mysql,或某个微服务(订单服务、库存服务等)
两阶段事务-全局提交
我们采用用户下单使用余额+红包支付来2阶段提交的具体分析
假设用户下单操作来自3个系统下单系统、资金账户系统、红包账户系统,下单成功后,支付需要同时调用资金账户服务和红包服务完成支付。
2阶段提交,意思就是一次事务分为2个阶段。如上图:
第一阶段,是事务准备
协调者TM询问所有参与者是否可以提交事务?
如果参与者的事务操作实际执行成功 ,则返回一个“同意”消息
如果参与者的事务操作实际执行失败,则返回一个“终止”消息
第二阶段:事务提交
协调者根据所有参与者的应答结果判定是否事务可以全局提交的决定,并通过所有参与者执行该决定
如果在第一阶段所有参与者都同意提交,则协调者让所有参与者都提交事务
如果在第一阶段其中某个参与者终止提交,则协调者让所有参与者都回滚事务。
两阶段事务-全局回滚
如果任一参与者在第一阶段响应消息为“终止”,或响应超时:
协调者向所有参与者发送“回滚操作”的请求。
然后参与者向协调者发送“回滚完成”的消息。
感谢观看!