Seata 全局事務(wù)管理:如何配置和使用 Seata 的事務(wù)管理功能?
Seata 是一個(gè)開(kāi)源的分布式事務(wù)解決方案,旨在為微服務(wù)架構(gòu)中的分布式事務(wù)提供統(tǒng)一的事務(wù)管理功能。它通過(guò)全局事務(wù)和分支事務(wù)的概念,解決了跨服務(wù)和跨數(shù)據(jù)庫(kù)的一致性問(wèn)題。接下來(lái)我們將深入探討如何配置和使用 Seata 的事務(wù)管理功能,重點(diǎn)介紹全局事務(wù) ID、分支事務(wù)、事務(wù)狀態(tài)等核心概念,并通過(guò)多個(gè)代碼示例展示如何在 Spring Boot 和 Spring Cloud 中使用 Seata。
1、核心概念
在 Seata 中,分布式事務(wù)被分為兩大類:
1、全局事務(wù)(Global Transaction) 全局事務(wù)是一個(gè)跨多個(gè)微服務(wù)或系統(tǒng)的事務(wù),它由一個(gè)全局事務(wù) ID 唯一標(biāo)識(shí)。全局事務(wù)可以包括多個(gè)分支事務(wù),它的目標(biāo)是確保多個(gè)分支事務(wù)在最終提交或回滾時(shí)保持一致性。
2、分支事務(wù)(Branch Transaction) 分支事務(wù)是全局事務(wù)的一部分,通常對(duì)應(yīng)于具體的操作,如調(diào)用遠(yuǎn)程服務(wù)、訪問(wèn)數(shù)據(jù)庫(kù)等。分支事務(wù)通常是短時(shí)間的,并由具體的資源管理器(如數(shù)據(jù)庫(kù)或消息隊(duì)列)負(fù)責(zé)處理。
3、事務(wù)狀態(tài)(Transaction Status) Seata 中的事務(wù)狀態(tài)包括:
- Begin:事務(wù)開(kāi)始
- Commit:事務(wù)提交
- Rollback:事務(wù)回滾
4、Seata 的角色
- TC(Transaction Coordinator):負(fù)責(zé)全局事務(wù)的協(xié)調(diào)
- RM(Resource Manager):管理和操作分支事務(wù),通常是數(shù)據(jù)庫(kù)、消息隊(duì)列等
- TM(Transaction Manager):負(fù)責(zé)發(fā)起全局事務(wù),通常集成在服務(wù)代碼中
2、如何配置 Seata 和使用全局事務(wù)
2.1、添加 Seata 依賴
在 Spring Boot 項(xiàng)目中,可以通過(guò)以下 Maven 依賴來(lái)引入 Seata 相關(guān)依賴:
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.6.1</version>
</dependency>
2.2、Seata 配置
Seata 需要一個(gè)配置中心來(lái)存儲(chǔ)全局事務(wù)的狀態(tài)。最常見(jiàn)的配置是通過(guò) Nacos 或 Zookeeper 實(shí)現(xiàn)。下面是一個(gè)典型的 application.yml
配置示例:
server:
port: 8080
spring:
application:
name: seata-demo
seata:
tx-service-group: my_test_tx_group # 設(shè)置全局事務(wù)組名
config:
type: nacos
nacos:
server-addr: localhost:8848
namespace: public
group: SEATA_GROUP
transport:
type: TCP
server: 127.0.0.1:8091
2.3、配置 Seata 服務(wù)端
Seata 服務(wù)端需要配置數(shù)據(jù)庫(kù)或其他存儲(chǔ)系統(tǒng)來(lái)管理事務(wù)。以 Nacos 為例,配置項(xiàng)如下:
transport:
type: TCP
server: 127.0.0.1:8091
store:
mode: db
db:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/seata
user: root
password: root
2.4、啟用 Seata 全局事務(wù)
在 Spring Boot 中,你可以使用 @GlobalTransactional
注解來(lái)啟用全局事務(wù)。例如,下面的代碼展示了一個(gè)簡(jiǎn)單的全局事務(wù)管理:
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
@GlobalTransactional
public void createOrder() {
// 模擬創(chuàng)建訂單操作
System.out.println("Order Created");
}
}
3、使用 Seata API 提交、回滾事務(wù)
Seata 提供了多種 API 來(lái)操作全局事務(wù),例如提交事務(wù)、回滾事務(wù)等。以下是如何使用 Seata API 來(lái)管理事務(wù)。
3.1、事務(wù)開(kāi)始
當(dāng)你調(diào)用 @GlobalTransactional
注解的服務(wù)時(shí),Seata 會(huì)自動(dòng)啟動(dòng)全局事務(wù)并生成一個(gè)全局事務(wù) ID。在代碼中,你不需要手動(dòng)創(chuàng)建事務(wù),Seata 會(huì)自動(dòng)管理它。
3.2、提交事務(wù)
如果所有的分支事務(wù)都成功執(zhí)行,Seata 會(huì)嘗試提交全局事務(wù)。你可以通過(guò)調(diào)用 GlobalTransactionContext
來(lái)手動(dòng)提交事務(wù)。
import io.seata.core.context.GlobalTransactionContext;
import io.seata.tm.api.GlobalTransaction;
public class OrderService {
public void commitTransaction() {
GlobalTransaction globalTransaction = GlobalTransactionContext.getCurrentOrCreate();
globalTransaction.commit();
}
}
3.3、回滾事務(wù)
如果出現(xiàn)任何錯(cuò)誤,或者你需要回滾整個(gè)事務(wù),可以調(diào)用 GlobalTransactionContext
提供的 rollback()
方法來(lái)回滾全局事務(wù)。
public void rollbackTransaction() {
GlobalTransaction globalTransaction = GlobalTransactionContext.getCurrentOrCreate();
globalTransaction.rollback();
}
4、分支事務(wù)的處理
4.1、分支事務(wù)的注冊(cè)
在 Seata 中,分支事務(wù)是由 Resource Manager (RM) 進(jìn)行管理的。一個(gè)分支事務(wù)通常會(huì)在服務(wù)調(diào)用或數(shù)據(jù)庫(kù)操作之前進(jìn)行注冊(cè)。你可以通過(guò) Seata 提供的 API 注冊(cè)分支事務(wù)。
假設(shè)我們?cè)谧鲆粋€(gè)訂單和支付的操作,訂單服務(wù)和支付服務(wù)是兩個(gè)分支事務(wù)。
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
@Autowired
private DataSourceProxy dataSource;
public void createOrderAndPay() {
// 先創(chuàng)建訂單
createOrder();
// 然后支付
makePayment();
}
private void createOrder() {
// 訂單創(chuàng)建邏輯
System.out.println("Creating Order");
}
private void makePayment() {
// 支付邏輯
System.out.println("Making Payment");
}
}
4.2、分支事務(wù)的提交和回滾
分支事務(wù)的提交和回滾通常是由 RM
管理器根據(jù)全局事務(wù)的狀態(tài)進(jìn)行的。如果所有分支事務(wù)都成功,Seata 會(huì)提交這些事務(wù);如果某個(gè)分支事務(wù)失敗,Seata 會(huì)回滾所有相關(guān)事務(wù)。
5、Seata 和 Spring Cloud 整合
如果你在使用 Spring Cloud 微服務(wù)框架,Seata 提供了與 Spring Cloud 的集成支持。以下是如何配置 Spring Cloud 和 Seata。
5.1、Spring Cloud 集成 Seata
首先,在 Spring Cloud 的 application.yml
中添加 Seata 的配置:
seata:
tx-service-group: my_test_tx_group
config:
type: nacos
nacos:
server-addr: localhost:8848
namespace: public
group: SEATA_GROUP
transport:
type: TCP
server: 127.0.0.1:8091
然后,像 Spring Boot 一樣,通過(guò) @GlobalTransactional
注解來(lái)啟動(dòng)全局事務(wù)。
5.2、跨服務(wù)的全局事務(wù)管理
在微服務(wù)架構(gòu)中,你可能會(huì)有多個(gè)服務(wù)進(jìn)行分布式事務(wù)的管理。例如,訂單服務(wù)和支付服務(wù)的事務(wù)可以通過(guò) Seata 進(jìn)行跨服務(wù)的全局事務(wù)管理。你只需要確保每個(gè)微服務(wù)都啟用了 Seata 并配置了正確的事務(wù)組名。
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private PaymentService paymentService;
@GlobalTransactional
@RequestMapping("/createOrder")
public String createOrder() {
// 創(chuàng)建訂單并支付
orderService.createOrder();
paymentService.makePayment();
return "Order Created and Payment Made";
}
}
6、總結(jié)
Seata 作為一個(gè)分布式事務(wù)管理工具,為微服務(wù)架構(gòu)提供了一種高效、簡(jiǎn)單的事務(wù)管理解決方案。通過(guò)配置 Seata 的全局事務(wù)和分支事務(wù),并結(jié)合 Spring Boot 或 Spring Cloud,可以幫助開(kāi)發(fā)人員輕松管理跨服務(wù)和跨數(shù)據(jù)庫(kù)的事務(wù)一致性。
關(guān)鍵點(diǎn)回顧:
- 全局事務(wù) 和 分支事務(wù) 是 Seata 事務(wù)模型的核心。
- @GlobalTransactional 注解可以自動(dòng)啟動(dòng)全局事務(wù)。
- 事務(wù)的提交和回滾通過(guò) Seata API 進(jìn)行管理。
- Seata 可以與 Spring Boot 和 Spring Cloud 平臺(tái)進(jìn)行無(wú)縫集成。
通過(guò)本文的示例代碼,你可以在實(shí)際項(xiàng)目中輕松實(shí)現(xiàn) Seata 的分布式事務(wù)管理,并確保多個(gè)微服務(wù)之間的事務(wù)一致性。