共计 4327 个字符,预计需要花费 11 分钟才能阅读完成。
源码地址:GitHub·点这里 || GitEE·点这里
一、Seata 简介
1、Seata 组件
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简略易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA、XA 事务模式,为用户打造一站式的分布式解决方案。
2、反对模式
AT 模式
- 基于反对本地 ACID 事务的关系型数据库。
- Java 利用,通过 JDBC 拜访数据库。
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,开释本地锁和连贯资源。
二阶段:提交异步化,十分疾速地实现。回滚通过一阶段的回滚日志进行反向弥补。
TCC 模式
一个分布式的全局事务,整体是两阶段提交的模型,全局事务是由若干分支事务组成的,分支事务要满足两阶段提交的模型要求,即须要每个分支事务都具备本人的:
一阶段 prepare 行为
二阶段 commit 或 rollback 行为
Saga 模式
Saga 模式是 SEATA 提供的长事务解决方案,在 Saga 模式中,业务流程中每个参与者都提交本地事务,当呈现某一个参与者失败则弥补后面曾经胜利的参与者,一阶段正向服务和二阶段弥补服务都由业务开发实现。
XA 模式
XA 是一个分布式事务协定,对业务无侵入的分布式事务解决方案,XA 提交协定须要事务参与者的数据库反对,XA 事务具备强一致性,在两阶段提交的整个过程中,始终会持有资源的锁,性能不现实的毛病很显著。
二、服务端部署
1、下载组件包
1.2 版本:seata-server-1.2.0.zip
解压目录
- bin:寄存服务端运行启动脚本;
- lib:寄存服务端依赖的资源 jar 包;
- conf:配置文件目录。
2、批改配置
file.conf 配置
mode:db 即应用数据库存储事务信息,这里还能够抉择 file 存储形式。
file 模式为单机模式,全局事务会话信息内存中读写并长久化本地文件 root.data,性能较高;
db 模式为高可用模式,全局事务会话信息通过 db 共享,相应性能差些;
redis 模式 Seata-Server 1.3 及以上版本反对, 性能较高, 存在事务信息失落危险, 请提前配置适合以后场景的 redis 长久化配置.
store {
## store mode: file、db
mode = "db"
db {
datasource = "druid"
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata_server"
user = "root"
password = "123456"
minConn = 5
maxConn = 30
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
registry.conf 配置
这里抉择 eureka 作为注册核心,seata-server 也要作为一个服务增加到注册核心,不应用配置核心所以 config 配置默认即可。
registry {
# file、nacos、eureka、redis、zk、consul、etcd3、sofa
type = "eureka"
eureka {
serviceUrl = "http://localhost:8761/eureka"
application = "default"
weight = "1"
}
}
3、事务管理表
须要在 seata-server 即上述配置的 MySQL 库中建设 3 张事务管理表:
- 全局事务:global_table
- 分支事务:branch_table
- 全局锁:lock_table
- 事务回滚:undo_log
- SQL 脚本:mysql-script 目录
4、启动命令
Linux 环境:sh seata-server.sh
三、业务服务搭建
1、代码构造
- seata-eureka:注册核心
- seata-order:订单服务
- seata-account:账户服务
- seata-inventor:库存服务
- seata-client:客户端服务
- account-feign:账户 Feign 接口
- inventory-feign:库存 Feign 接口
- order-feign:订单 Feign 接口
申请链路 :客户端 -> 订单 -> 账户 + 库存,测试整个流程的分布式事务问题。
2、数据库构造
- seata_server:seata 组件服务端依赖库
- seata_account:模仿账户数据库
- seata_inventor:模仿库存数据库
- seata_order:模仿订单数据库
各个库脚本地位:mysql-script/data-biz.sql
3、启动服务
顺次启动:注册核心,库存服务,账户服务,订单服务,客户端服务;
Eureka 服务列表如下:
四、Seata 用法详解
1、Seata 根底配置
几个根底服务的配置形式一样。
conf 配置
file.conf 重点关注上面内容,事务组的名称,须要在 yml 文件中应用。
my_test_tx_group = "default"
registry.conf:是注册核心的抉择。
2、数据库配置
留神这里的事务组名称配置。
spring:
# 事务组的名称
cloud:
alibaba:
seata:
tx-service-group: my_test_tx_group
# 数据源配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/seata_account
username: root
password: 123456
将数据库整体由 Seata 进行代理治理,外围 API:DataSourceProxy。
@Configuration
public class SeataAccountConfig {@Value("${spring.application.name}")
private String applicationName;
@Bean
public GlobalTransactionScanner globalTransactionScanner() {return new GlobalTransactionScanner(applicationName, "test-tx-group");
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid")
public DruidDataSource druidDataSource() {return new DruidDataSource() ;
}
@Primary
@Bean("dataSource")
public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {return new DataSourceProxy(druidDataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSourceProxy);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/*.xml"));
sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
return sqlSessionFactoryBean.getObject();}
}
3、业务代码
外围注解:GlobalTransactional,治理整体的分布式事务。
@Service
public class OrderServiceImpl implements OrderService {private final Logger LOGGER = LoggerFactory.getLogger(OrderServiceImpl.class);
@Resource
private OrderMapper orderMapper ;
@Resource
private AccountFeign accountFeign ;
@Resource
private InventoryFeign inventoryFeign ;
@GlobalTransactional
@Override
public Integer createOrder(String orderNo) {LOGGER.info("Order 生成中"+orderNo);
// 本服务下订单库
Integer insertFlag = orderMapper.insert(orderNo) ;
// 基于 feign 接口解决账户和库存
accountFeign.updateAccount(10L) ;
inventoryFeign.updateInventory(10) ;
return insertFlag ;
}
}
测试流程:在任意服务下抛出异样,察看整体的事务状态,察看是否有整体的事务管制成果。
五、源代码地址
GitHub 地址:知了一笑
https://github.com/cicadasmile/spring-cloud-base
GitEE 地址:知了一笑
https://gitee.com/cicadasmile/spring-cloud-base
举荐浏览:架构设计系列
题目 |
---|
架构设计:单服务. 集群. 分布式,根本区别和分割 |
架构设计:分布式业务零碎中,全局 ID 生成策略 |
架构设计:分布式系统调度,Zookeeper 集群化治理 |
架构设计:接口幂等性准则,防反复提交 Token 治理 |
架构设计:缓存管理模式,监控和内存回收策略 |
架构设计:异步解决流程,多种实现模式详解 |
架构设计:高并发流量削峰,共享资源加锁机制 |
架构设计:分布式服务,库表拆分模式详解 |
架构设计:分布式事务①概念简介和基础理论 |
架构设计:基于电商交易流程,图解 TCC 事务分段提交 |
架构设计:基于消息中间件,图解柔性事务一致性 |