1、Seata 簡介
1.1 Seata是什麼
Seata 是一款開源的分散式事務解決方案,致力於提供高效能和簡單易用的分散式事務服務。Seata 將為使用者提供了 AT、TCC、SAGA 和 XA 事務模式,為使用者打造一站式的分散式解決方案。AT模式是阿里首推的模式,阿里雲上有商用版本的GTS(Global Transaction Service 全域性事務服務)。
1.2 Seata的三大角色
在Seata的架構中,一共有三大角色:
TC(Transaction Coordinator)- 事務協調者
維護全域性和分支事務的狀態,驅動全域性事務提交或回滾。
TM(Transaction Manager)- 事務管理器
定義全域性事務的範圍:開始全域性事務、提交或回滾全域性事務
RM(Resource Manager)- 資源管理器
管理分支事務處理的資源,與TC交談以註冊分支事務和報告分支事務的狀態,並驅動分支事務提交或回滾。
其中,TC為單獨部署的Server服務端,TM和RM為嵌入到應用中的Client客戶端。
1.3 一個分散式事務的生命週期
部落格參考:https://blog.csdn.net/qq_41910252/article/details/122517092
2、安裝seata
2.1 下載安裝包和原始碼
下載地址:https://github.com/seata/seata/releases
2.2 修改registry,conf 上傳配置檔案到nacos
2.2.1 複製 registry 檔案
2.2.2 修改配置
2.3 上傳到nacos的配置列表
使用git視窗# sh nacos-config.sh -h localhost -p 8848
資料庫8的修改一下driverClassName
加時區:
2.3 修改config.txt 啟動seate 註冊到nacos
2.3.1 複製config.txt
2.3.2 修改config.txt
2.3.3 建立seata資料庫
2.3.4 啟動seata
seata-server.bat -h 127.0.0.1 -p 8091
3、專案演示
3.1 模組說明
3.2 依賴
<!-- nacso註冊,feign 依賴不再贅述 -->
<!-- seata -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
3.4 配置
3.4.1 undo_log表
3.2.1.1 資料庫指令碼
3.2.1.2 配置
# 服務名
spring:
# 資料來源配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/seate_order?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
username: root
password: root
initialization-mode: always # 支援微服務應用啟動時自動執行schema。sql指令碼
3.2.1.3 後面專案啟動後指令碼刷入order庫,和prod庫
3.4.2 seata配置
# seata client配置(頂格寫)
seata:
enabled: true # 開啟Seata
tx-service-group: my_test_tx_group # 事務服務分組(可以每個應用單獨取名, 也可以使用相同的名字)即要和上文中的seata-server的context.txt中service.vgroupMapping.seata_test_tx_group=default一致
enable-auto-data-source-proxy: true # 自動開啟資料來源代理
registry:
type: nacos # 使用nacos註冊中心,預設file,訪問seata server(TC)
nacos:
server-addr: 127.0.0.1:8848 # seata server 所在的nacos服務地址
application: seata-server # seata server 的服務名seata-server ,如果沒有修改可以不配
group: SEATA_GROUP # seata server 所在的組,預設就是SEATA_GROUP,沒有改也可以不配
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848 # seata server 所在的nacos服務地址
group: SEATA_GROUP # seata server 所在的組,預設就是SEATA_GROUP,沒有改也可以不配
service:
vgroup-mapping:
my_test_tx_group: default # 事務群組(必須與seata-server保持一致)
disable-global-transaction: false # 是否禁用全域性事務開關
client:
rm:
report-success-enable: false #是否上報一階段成功
3.5 主要程式碼
3.5.1 order模組的下單和遠端呼叫扣減庫存
全域性事務註解:@GlobalTransactional
/**
* Created On : 1/12/2022.
* <p>
* Author : huayu
* <p>
* Description: order模組 下單,呼叫遠端扣減庫存
*/
@Service
@Slf4j
public class KgcMallSeataOrderServiceImpl implements KgcMallSeataOrderService {
@Autowired
private KgcMallSeataOrderRepository kgcMallSeataOrderRepository; //執行 下單
@Autowired
private KgcMallSeataProdFeignService kgcMallSeataProdFeignService; // 遠端呼叫 執行 扣減庫存
@Override
@GlobalTransactional // 分散式事務註解,使用的全域性事務,後續所有微服務涉及事務操作,都會被統一管理
public KgcMallSeataOrder createSeataOrder(KgcMallSeataOrder kgcMallSeataOrder, Integer count) {
//將分散式事務訂單入庫
KgcMallSeataOrder seataOrder = kgcMallSeataOrderRepository.save(kgcMallSeataOrder);
//遠端呼叫商品業務介面,扣減庫存
kgcMallSeataProdFeignService.invokeSeataProductStockFeign(kgcMallSeataOrder.getProdId(), count);
//返回下單詳情
return seataOrder;
}
}
3.5.2 prod 模組 扣減庫存
事務註解:@Transactional
/**
* Created On : 1/12/2022.
* <p>
* Author : huayu
* <p>
* Description: prod模組 扣減庫存
*/
@Service
public class KgcMallProdServiceImpl implements KgcMallProdService {
@Autowired
private KgcMallSeataProdRepository kgcMallSeataProdRepository; //執行 扣減庫存
@Override
@Transactional
public KgcMallSeataProduct subSeataProductStock(Integer pid, Integer count) {
//查詢商品庫存
KgcMallSeataProduct kgcMallSeataProduct = kgcMallSeataProdRepository.findById(pid).orElse(null);
//判斷商品是否存在
if (kgcMallSeataProduct != null) {
kgcMallSeataProduct.setProdStock(kgcMallSeataProduct.getProdStock() - count);
}
KgcMallSeataProduct saveKgcMallSeataProduct = kgcMallSeataProdRepository.save(kgcMallSeataProduct);
//模擬執行時異常
if (count == 10) {
int a = 10 / 0;
}
//返回詳情
return saveKgcMallSeataProduct;
}
}
4 測試
4.1 正常下單
4.1.1 發起請求
4.1.2 檢視資料庫
order資料庫下單:
prod資料庫扣減庫存:
扣減前:
扣減後: