微服務整合Spring Cloud Alibaba Seata (二) 客戶端連線

sowler發表於2024-04-03

透過上篇文章後我們的Seata服務就部署成功了,如果還不清楚怎麼部署或者還沒有部署Seata服務的朋友可以看我寫的上篇文章進行服務部署。Seata部署步驟:https://www.cnblogs.com/sowler/p/18108102 接下來我們來介紹在專案中如何使用Seata,溫馨提示:請確保自己目前已經整合了一套Spring Cloud微服務架構,以更好的實操Seata。本篇只寫Seata相關的知識。

1、引入Maven依賴

首先我們需要在需要使用seata的模組引入maven依賴seata 對應版本1.3.0

       <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
           <!--自帶的版本可能會和Spring Cloud Alibaba對應的版本不一致 排除到重新引入相對應的版本 如果一致就不需要排除-->
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

2、下載資料庫表檔案

Seata實現事務,需要依賴於資料表進行事務處理,所以我們需要下載seata對應版本的資料表匯入各各模組的資料庫裡面。下載路徑:incubator-seata/script/client/at/db/mysql.sql at v1.3.0 · apache/incubator-seata · GitHub下載成功後匯入到庫裡面。

3、在使用者模組配置加入配置

seata:
  enabled: true
  application-id: ${spring.application.name}
  # 客戶端和服務端在同一個事務組  default_tx_group
  tx-service-group: order_tx_group
  # 自動資料來源代理
  enable-auto-data-source-proxy: true
  # 資料來源代理模式(分散式事務方案)
  data-source-proxy-mode: AT
  # 事務群組,配置項值為TC叢集名,需要與服務端保持一致
  service:
    # 跟服務端配置保持一致
    vgroup-mapping:
      order_tx_group: default
      order-public: default
      default_tx_group: default
    enable-degrade: false
    disable-global-transaction: false
    grouplist:
      default: 127.0.0.1:8091

4、在訂單模組配置中加入配置

seata:
  enabled: true
  application-id: ${spring.application.name}
  # 客戶端和服務端在同一個事務組  default_tx_group
  tx-service-group: order_tx_group
  # 自動資料來源代理
  enable-auto-data-source-proxy: true
  # 資料來源代理模式(分散式事務方案)
  data-source-proxy-mode: AT
  # 事務群組,配置項值為TC叢集名,需要與服務端保持一致
  service:
    # 跟服務端配置保持一致
    vgroup-mapping:
      order_tx_group: default
      order-public: default
      default_tx_group: default
    enable-degrade: false
    disable-global-transaction: false
    grouplist:
      default: 127.0.0.1:8091

在需要事務的實現類業務方法上面加入@GlobalTransactional註解實現事務

    @Override
    @GlobalTransactional(rollbackFor = Exception.class,timeoutMills = 30000,name = "order_tx_group") 
	//rollbackFor 報錯異常回滾	 timeoutMills 超時時間 		name當前使用的那個事務組
    public List<UserExternal> selectUserAll() {
        //新增blog
        Blog blog = new Blog();
        blog.setUid(UUID.randomUUID().toString());
        blog.setTitle("dubbo事務測試Test");
        blog.setContent("dubbo事務測試Test啊的伺服器打");
        blog.setSummary("12");
        blog.setTagUid("3c16b9093e9b1bfddbdfcb599b23d835");
        blogService.insert(blog);
        //處理相關邏輯
        Response<List<UserExternal>> response = userExternalService.selectUserAll();
//        boolean flag = true;
//        if (flag == true){
//            throw new ParamException(500,"使用者模組出現錯誤,需要回滾");
//        }
        UserExternal user = new UserExternal();
        user.setUserName("dubbo事務");
        user.setAccount("system");
        user.setEmail("dubbo@gemail.com");
        Response insert = userExternalService.insert(user);
        System.out.println(insert);
        return response.getModel();
    }

5、測試事務是否觸發

啟動專案進行資料測試。呼叫介面新增資料發現在每個模組中會有seata日誌輸出

訂單模組 新增blog表:

2024-04-03 15:09:16.383 INFO  -[DefaultGlobalTransaction.java:108]- Begin new global transaction [172.25.96.1:8091:518805861666131968]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ff3054] was not registered for synchronization because synchronization is not active
JDBC Connection [io.seata.rm.datasource.ConnectionProxy@34a12e67] will not be managed by Spring
==>  Preparing: INSERT INTO tb_blog (uid, title, summary, content, tag_uid) VALUES (?, ?, ?, ?, ?) 
==> Parameters: 1c7cd2f7-a690-4942-b01f-9e1b76eb8b0e(String), dubbo事務測試Test(String), 12(String), dubbo事務測試Test啊的伺服器打(String), 3c16b9093e9b1bfddbdfcb599b23d835(String)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ff3054]
Response(code=200, msg=success, model=null)
2024-04-03 15:09:16.609 INFO  -[DefaultGlobalTransaction.java:143]- [172.25.96.1:8091:518805861666131968] commit status: Committed
2024-04-03 15:09:16.693 INFO  -[RmBranchCommitProcessor.java:56]- rm client handle branch commit process:xid=172.25.96.1:8091:518805861666131968,branchId=518805861913595905,branchType=AT,resourceId=jdbc:mysql://127.0.0.1:3306/order-mode,applicationData=null
2024-04-03 15:09:16.693 INFO  -[AbstractRMHandler.java:96]- Branch committing: 172.25.96.1:8091:518805861666131968 518805861913595905 jdbc:mysql://127.0.0.1:3306/order-mode null
2024-04-03 15:09:16.693 INFO  -[AbstractRMHandler.java:104]- Branch commit result: PhaseTwo_Committed

看第一行:Begin new global transaction 開始一個新的全域性事務 說明seata配置已經生效。

關鍵資訊:

2024-04-03 15:09:16.383 INFO  -[DefaultGlobalTransaction.java:108]- Begin new global transaction 

2024-04-03 15:09:16.609 INFO  -[DefaultGlobalTransaction.java:143]- [172.25.96.1:8091:518805861666131968] commit status: Committed
2024-04-03 15:09:16.693 INFO  -[RmBranchCommitProcessor.java:56]- rm client handle branch commit process:xid=172.25.96.1:8091:518805861666131968,branchId=518805861913595905,branchType=AT,resourceId=jdbc:mysql://127.0.0.1:3306/order-mode,applicationData=null
2024-04-03 15:09:16.693 INFO  -[AbstractRMHandler.java:96]- Branch committing: 172.25.96.1:8091:518805861666131968 518805861913595905 jdbc:mysql://127.0.0.1:3306/order-mode null
2024-04-03 15:09:16.693 INFO  -[AbstractRMHandler.java:104]- Branch commit result: PhaseTwo_Committed

使用者模組 新增使用者資訊:

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6d327c7] was not registered for synchronization because synchronization is not active
JDBC Connection [io.seata.rm.datasource.ConnectionProxy@782accbc] will not be managed by Spring
==>  Preparing: INSERT INTO tb_user (user_name, account, email, create_by, create_time) VALUES (?, ?, ?, ?, ?) 
==> Parameters: dubbo事務(String), system(String), dubbo@gemail.com(String), System(String), 1712128156490(Long)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6d327c7]
2024-04-03 15:09:16.707 INFO  -[RmBranchCommitProcessor.java:56]- rm client handle branch commit process:xid=172.25.96.1:8091:518805861666131968,branchId=518805862223974401,branchType=AT,resourceId=jdbc:mysql://127.0.0.1:3306/user-mode,applicationData=null
2024-04-03 15:09:16.707 INFO  -[AbstractRMHandler.java:96]- Branch committing: 172.25.96.1:8091:518805861666131968 518805862223974401 jdbc:mysql://127.0.0.1:3306/user-mode null
2024-04-03 15:09:16.707 INFO  -[AbstractRMHandler.java:104]- Branch commit result: PhaseTwo_Committed

關鍵資訊:

2024-04-03 15:09:16.707 INFO  -[RmBranchCommitProcessor.java:56]- rm client handle branch commit process:xid=172.25.96.1:8091:518805861666131968,branchId=518805862223974401,branchType=AT,resourceId=jdbc:mysql://127.0.0.1:3306/user-mode,applicationData=null
2024-04-03 15:09:16.707 INFO  -[AbstractRMHandler.java:96]- Branch committing: 172.25.96.1:8091:518805861666131968 518805862223974401 jdbc:mysql://127.0.0.1:3306/user-mode null
2024-04-03 15:09:16.707 INFO  -[AbstractRMHandler.java:104]- Branch commit result: PhaseTwo_Committed

檢視資料表undo_log日誌資訊,發現該資訊在事務執行時,事務資訊會新增到每個模組的undo_log日誌表中。當執行成功後,會刪除undo_log表的日誌資訊。

當事務開始執行時,檢視seata資料庫會發現在global_table表中會生成一條事務資料:

當方法執行在訂單模組處理資料的時候,會在訂單資料庫的undo_log表中新增一條資料:

當方法執行到使用者模組中時,在使用者資料庫的undo_log表中也會新增一條資料

透過上面可以發現seata是透過xid欄位的全域性ID進行事務控制的。我們還可以測試一下,當呼叫的使用者模組出現異常了,事務是如何實現回滾的。好了到此seata的在專案中的使用就介紹完畢了,我們還可以學習一些seata的執行原理來更好的使用seata。

相關文章