SpringCloudAlibaba技术栈学习(八)Seata分布式事务解决方案

第八章 Seata-分布式事务

代码地址:源码地址

1. 事务简介

事务特性:
A:原子性(Atomicity),一个事务中的所有操作,要么全部完成,要么全部不完成
B:一致性(Consistency),在一个事务执行之前和执行之后数据库都必须处于一致性状态
C:隔离性(Isolation),在并发环境中,当不同的事务同时操作相同的数据时,事务之间互不影响
D:持久性(Durability),指的是只要事务成功结束,它对数据库所做的更新就必须永久的保存下来
分布式架构下的事务问题:一个大事务下可能涉及到多个微服务需要进行数据库操作,可能一个微服务操作成功,一个操作失败,不好保证事务的一致性,原子性。

2. 分布式事务解决方案

2.1 全局事务

需要三种角色:
AP: Application 应用系统 (微服务)
TM: Transaction Manager 事务管理器 (全局事务管理)
RM: Resource Manager 资源管理器 (数据库)
借用教程里的图片,教程地址:视频地址
在这里插入图片描述
表决,执行

2.2 可靠消息服务

利用第六章说到的MQ事务消息,解决分布式事务问题。
在这里插入图片描述
在第六章,我们实现的是order+user两个微服务的事务消息,这里再加一个product减库存的事务进去,实现步骤:
①在product模块创建service类,继承RocketMQListener<>泛型里填消息传来的对象类,Order
②添加注解RocketMQMessageListener指定监听的消息主题
③重写onMessage方法,实现减库存操作。代码如下:

@Service
@RocketMQMessageListener(
        consumerGroup = "shop-user"
        ,topic = "order-topic"
)
public class ReduceInventoryService implements RocketMQListener<Order> {
    @Autowired
    ProductService productService;
    @Override
    public void onMessage(Order order) {
        productService.reduceInventory(order.getPid(),order.getNumber());
    }
}

2.3 最大努力通知

2.4 TCC事务

Try,Confirm,Cancel类似于全局事务

3. Seata

3.1 Seata整合

①首先下载seata,下载地址
②修改配置,这部分由于各版本不同,修改的地方也不尽相同。大概就是把类型设置成nacos还有加入service.vgroup_mapping.service-order=default这种格式的配置,和微服务一一对应。
③初始化配置:

cd conf
nacos-config.sh 127.0.0.1

初始化完成后,可以在nacos的配置列表中看到很多seata的配置。
④启动seate

cd bin
seata-server.bat -p 9000 -m file

启动成功后可以在nacos的服务列表中看到seata的服务。serverAddr
⑤在数据库中创建表:

CREATE TABLE `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`branch_id` BIGINT(20) NOT NULL,
`xid` VARCHAR(100) NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGBLOB NOT NULL,
`log_status` INT(11) NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = INNODB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8;

⑥在微服务中引入依赖:

<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

⑦在各个微服务的config包下编写配置类:

@Configuration
public class DataSourceProxyConfig {
	@Bean
	@ConfigurationProperties(prefix = "spring.datasource")
	public DruidDataSource druidDataSource() {
		return new DruidDataSource();
	} 
	@Primary
	@Bean
	public DataSourceProxy dataSource(DruidDataSource druidDataSource) {
		return new DataSourceProxy(druidDataSource);
	}
}

⑧把seata conf路径下的的registry.conf文件复制到各个微服务的resource包中。
⑨修改各个微服务的bootstrap文件,使其读取seata的配置。(这里微服务自己的配置不知道怎么放到nacos上去了,只能放在application.yml里面)

spring:
	application:
		name: service-product
	cloud:
		nacos:
			config:
				server-addr: localhost:8848 # nacos的服务端地址
				namespace: public
				group: SEATA_GROUP
		alibaba:
			seata:
				tx-service-group: ${spring.application.name}

⑩在事务的开始添加注解@GlobalTransactional即可利用seata完成分布式事务的处理。

3.2 Seata运行流程

把分布式事务看成微服务调用微服务的过程,在事务开始的地方注册了一个全局的XID,之后每条分支的XID都与之相等。
在微服务调用另一个微服务时,由被调用的微服务注册分支事务,产生一个BranchID,这个分支事务的BranchID是独一无二的,但是XID和这条链路上的其他分支一样。
分支事务之中undo_log和业务逻辑共同操作,undo_log记录业务逻辑操作数据库前后的状态。
当分支事务处理完后,会上报处理结果,由TC判断是否回滚,

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页