自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何在 Spring Boot 中集成 Seata,解決分布式事務(wù)?

云計算 分布式
本文將詳細介紹如何在 Spring Boot 項目中集成 Seata,并通過具體的代碼案例實現(xiàn)分布式事務(wù)管理。以下內(nèi)容包括配置、代碼實現(xiàn)以及一些注意事項,幫助你快速上手。

在分布式系統(tǒng)中,服務(wù)之間往往涉及多個數(shù)據(jù)庫操作,這就需要一個可靠的分布式事務(wù)解決方案來確保數(shù)據(jù)的一致性。Seata(Simple Extensible Autonomous Transaction Architecture)是一個開源的分布式事務(wù)解決方案,提供了高性能和易用的分布式事務(wù)服務(wù)。

本文將詳細介紹如何在 Spring Boot 項目中集成 Seata,并通過具體的代碼案例實現(xiàn)分布式事務(wù)管理。以下內(nèi)容包括配置、代碼實現(xiàn)以及一些注意事項,幫助你快速上手。

整體步驟

1、準備工作:

  • 搭建 Seata Server 環(huán)境
  • 創(chuàng)建兩個模擬服務(wù) order-service 和 account-service,分別代表訂單和賬戶的服務(wù)
  • 準備一個 Eureka/Nacos 注冊中心(推薦 Nacos)

2、配置 Seata:

  • 在項目中引入 Seata 依賴
  • 配置 Seata 客戶端
  • 配置數(shù)據(jù)源代理

3、代碼實現(xiàn):

  • 使用 @GlobalTransactional 注解實現(xiàn)全局事務(wù)管理
  • 編寫業(yè)務(wù)邏輯和分布式事務(wù)示例

環(huán)境搭建

1、下載并啟動 Seata Server

從 Seata 官方倉庫下載 Seata Server:https://github.com/seata/seata/releases。解壓后,修改 conf/registry.conf 文件,將注冊中心改為 Nacos:

registry {
  type = "nacos"

  nacos {
    serverAddr = "localhost:8848"  # Nacos 服務(wù)地址
    namespace = ""                 # Nacos 命名空間
    cluster = "default"
  }
}

config {
  type = "nacos"

  nacos {
    serverAddr = "localhost:8848"
    namespace = ""
    group = "SEATA_GROUP"
  }
}

啟動 Seata Server:

sh bin/seata-server.sh

依賴引入

在兩個 Spring Boot 項目中添加以下依賴:

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.6.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.0.4.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2021.0.4.0</version>
</dependency>

配置文件詳解

以下是 application.yml 配置文件示例(order-service 和 account-service 的配置基本相同,區(qū)別僅在服務(wù)名上)。

order-service 配置

server:
  port: 8081

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/order_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: 123456
    type: com.zaxxer.hikari.HikariDataSource

mybatis-plus:
  mapper-locations: classpath:/mapper/*.xml

seata:
  enabled: true
  tx-service-group: my_tx_group  # 事務(wù)組名,與 Seata Server 配置一致

account-service 配置

server:
  port: 8082

spring:
  application:
    name: account-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/account_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: 123456
    type: com.zaxxer.hikari.HikariDataSource

mybatis-plus:
  mapper-locations: classpath:/mapper/*.xml

seata:
  enabled: true
  tx-service-group: my_tx_group  # 事務(wù)組名

數(shù)據(jù)庫表設(shè)計

訂單表 order_tbl

CREATE TABLE order_tbl (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id VARCHAR(64) NOT NULL,
  product_id VARCHAR(64) NOT NULL,
  count INT NOT NULL,
  money DECIMAL(10,2) NOT NULL,
  status INT DEFAULT 0 COMMENT '0:待支付, 1:已支付'
);

賬戶表 account_tbl

CREATE TABLE account_tbl (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id VARCHAR(64) NOT NULL,
  total DECIMAL(10,2) NOT NULL,
  used DECIMAL(10,2) NOT NULL,
  residue DECIMAL(10,2) NOT NULL
);

核心代碼實現(xiàn)

1、全局事務(wù)注解

Seata 提供了 @GlobalTransactional 注解,用于在分布式事務(wù)中管理多個服務(wù)調(diào)用。

2、OrderService 示例

OrderService 中模擬訂單創(chuàng)建邏輯,同時調(diào)用 AccountService 扣減賬戶余額。

代碼實現(xiàn)
@Service
@Slf4j
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private AccountClient accountClient; // Feign 客戶端調(diào)用 AccountService

    @GlobalTransactional(name = "create-order-transaction", rollbackFor = Exception.class)
    public void createOrder(String userId, String productId, int count, BigDecimal money) {
        log.info("-----> 開始新建訂單");
        Order order = new Order();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setCount(count);
        order.setMoney(money);
        order.setStatus(0);
        orderMapper.insert(order);

        log.info("-----> 訂單服務(wù)調(diào)用賬戶,開始扣減余額");
        accountClient.decreaseAccount(userId, money);
        log.info("-----> 訂單服務(wù)調(diào)用賬戶,扣減余額完成");

        log.info("-----> 修改訂單狀態(tài)為已完成");
        order.setStatus(1);
        orderMapper.updateById(order);

        log.info("-----> 訂單處理結(jié)束");
    }
}
Mapper 層
@Mapper
public interface OrderMapper extends BaseMapper<Order> {}

3、AccountService 示例

AccountService 中實現(xiàn)賬戶余額的扣減邏輯。

代碼實現(xiàn)
@Service
@Slf4j
public class AccountService {

    @Autowired
    private AccountMapper accountMapper;

    public void decreaseAccount(String userId, BigDecimal money) {
        log.info("-----> 扣減賬戶余額開始");
        accountMapper.decrease(userId, money);
        log.info("-----> 扣減賬戶余額結(jié)束");
    }
}
Mapper 層
@Mapper
public interface AccountMapper {

    @Update("UPDATE account_tbl SET residue = residue - #{money}, used = used + #{money} WHERE user_id = #{userId}")
    void decrease(@Param("userId") String userId, @Param("money") BigDecimal money);
}

4、Feign Client 示例

@FeignClient(name = "account-service")
public interface AccountClient {

    @PostMapping("/account/decrease")
    void decreaseAccount(@RequestParam("userId") String userId, @RequestParam("money") BigDecimal money);
}

測試分布式事務(wù)

啟動服務(wù)后,通過 Postman 或其他工具發(fā)送請求:

curl -X POST http://localhost:8081/order/create \
     -H "Content-Type: application/json" \
     -d '{
           "userId": "1",
           "productId": "1",
           "count": 10,
           "money": 100.00
         }'

重要注意事項

1、Seata Undo Log 表: 在每個數(shù)據(jù)庫中創(chuàng)建 undo_log 表,供 Seata 記錄回滾日志。

CREATE TABLE undo_log (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    branch_id BIGINT NOT NULL,
    xid VARCHAR(128) NOT NULL,
    context VARCHAR(128) NOT NULL,
    rollback_info LONGBLOB NOT NULL,
    log_status INT NOT NULL,
    log_created DATETIME NOT NULL,
    log_modified DATETIME NOT NULL,
    UNIQUE KEY ux_undo_log (xid, branch_id)
);

2、Seata 配置中心: 確保 Seata Server 的配置與服務(wù)端一致,事務(wù)組名必須統(tǒng)一。

總結(jié)

通過以上配置和代碼示例,我們實現(xiàn)了基于 Seata 的分布式事務(wù)管理。在實際項目中,可以根據(jù)業(yè)務(wù)需求靈活調(diào)整服務(wù)和表設(shè)計,確保數(shù)據(jù)一致性。

如果需要更深入的優(yōu)化或其他集成方法,可以進一步研究 Seata 的 AT、TCC 模式以及高可用配置。

責(zé)任編輯:武曉燕 來源: 架構(gòu)師秋天
相關(guān)推薦

2022-03-24 07:51:27

seata分布式事務(wù)Java

2022-06-27 08:21:05

Seata分布式事務(wù)微服務(wù)

2024-10-09 14:14:07

2022-06-21 08:27:22

Seata分布式事務(wù)

2020-12-09 09:14:57

SpringCloudSeata 分布式

2020-12-08 11:43:03

Spring Clou分布式Seata

2022-07-10 20:24:48

Seata分布式事務(wù)

2021-04-23 08:15:51

Seata XA AT

2023-11-06 13:15:32

分布式事務(wù)Seata

2022-06-14 10:47:00

分布式事務(wù)數(shù)據(jù)

2024-08-19 09:05:00

Seata分布式事務(wù)

2020-04-28 12:18:08

Seata模式分布式

2022-01-12 10:02:02

TCC模式 Seata

2023-01-06 09:19:12

Seata分布式事務(wù)

2022-07-03 14:03:57

分布式Seata

2020-05-28 09:35:05

分布式事務(wù)方案

2023-08-17 10:23:07

擴展方案

2024-12-02 09:19:44

2022-10-26 17:28:41

分布式事務(wù)seata

2024-01-26 08:18:03

點贊
收藏

51CTO技術(shù)棧公眾號