原始碼地址: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事務分段提交 |
| 架構設計:基于訊息中間件,圖解柔性事務一致性 |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/37659.html
標籤:Java
上一篇:des
下一篇:VC++運行錯誤
