1. 程式人生 > 其它 >SpringCloudAlibaba之Seata分散式事務

SpringCloudAlibaba之Seata分散式事務

一、什麼是Seata?

  Seata是一款開源的分散式事務解決方案,致力於提供高效能和簡單易用的分散式事務服務。Seata將為使用者提供了AT、TCC、SAGA 和XA事務模式,為使用者打造一站式的分散式解決方案。

  微服務中通常一次大的操作由不同的小操作組成的,這些小的操作分佈在不同的伺服器上,我們需要一定的方案來保證這些小操作要麼全部成功,要麼全部失敗。從本質上來說,就是為了保證不同資料庫的資料一致性。分散式事務就是一個保證資料一致性的解決方案。

  Seata分散式事務的處理包含全域性唯一事務ID和三個元件模組TC\TM\RM:

    TC事務協調器:維護全域性事務的執行狀態,負責協調並驅動全域性事務的提交或回滾。

    TM事務管理器:控制全域性事務的邊界,負責開啟一個全域性事務,並最終發起全域性提交或全域性回滾的決議。

    RM資源管理器:控制分支事務,負責分支註冊,狀態彙報,並接收事務協調器的指令,驅動分支事務的提交和回滾。

  以下是分散式事務的處理過程:

    1. TM向TC申請開啟一個全域性事務,全域性事務建立成功並生成一個全域性唯一的XID。

    2. XID在微服務呼叫鏈路的上下文中傳播。

    3. RM向TC註冊分支事務,將其納入XID對應全域性事務的管轄。

    4.TM向TC發起針對XID的全域性提交或回滾決議。

    5.TC排程XID下管轄的全部分支事務完成提交或回滾請求。

二、Seata的使用

  1、下載安裝:去http://seata.io/zh-cn下載對應版本,解壓到指定目錄並修改conf目錄下的file.conf配置檔案。主要配置自定義事務組的名稱,事務日誌的儲存模式為db和資料庫連線資訊。

    a.修改自定義事務組名稱:service.vgroup_mapping.my_test_tx_grou= "zqh_tx_group" 。

    b.修改事務日誌的儲存模式:store.mode="db"。

    c.建立資料庫,複製conf/db_store.sql程式碼去庫下執行建立表。

    d.配置資料連線:db.*下配置。

    e.修改conf/registry.conf檔案:設定registry.type="nacos", nacos{ serverAddr="localhost:8848",namsespace="" ,cluster=“default”},將Seata-server服務註冊到nacos註冊中心。

    f.啟動:先啟動nacos、後啟動seata(執行bin/seata-server.bat)。

  2、建立微服務對應的業務資料庫:每個微服務需要對應一個數據庫,為每個微服務的資料庫建立各自的回滾日誌表:複製conf/db_undo_log.sql在每個庫中執行一次。

  3、建立微服務(Controller-domain-Dao-Service-mapping程式碼結構):

    a.引入seata包,要注意排除jar包衝突:

<! --seata-->
<dependency>
   <grouprd>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-seata</artifactId> 
   <exclusions>
       <exclusion>
       <artifactid>seata-all</artifactId>
       <groupid>io.seata</groupId>
       </exclusion>
   </exclusions>
</dependency>
<dependency>
    <groupid>io.seata</grouprd>
    <artifactId>seata-all</artifactId>
    <version>0.9.0</version>
</dependency>

    b.配置yml檔案,指定事務組名稱:

server:
   port: 2001
spring:
   application:
      name: seata-order-service
   cloud:
      alibaba:
         seata:
           #自定義事務組名稱需要與seata-server中的對應
           tx-service-group: zqh_tx_group
         nacos:
           discovery:
             server-addr: localhost:8848
   datasource:
     driver-class-name: com.mysql.jdbc.Driver
     url: jdbc :mysql:/ /localhost:3306/ seata_order
     username: root
     password: 123456

    c.複製file.conf、registry.conf到微服務resources資原始檔夾。

    d.主啟動類增加@SpringBootApplication(exclude = DatasourceAutoconfiguration.class)註解取消資料來源的自動建立,選擇使用自定義的Seata資料來源DataSourceProxyConfig類進行代理。

    e.在呼叫微服務的介面服務類上增加@GlobalTransactional註解,完成微服務的一些列呼叫過程中的事務處理,當呼叫微服務過程中出現rollbackFor指定的異常,就會全域性回滾create()裡的任何呼叫,例如

/*建立訂單->呼叫庫存服務扣減庫存->呼叫賬戶服務扣減賬戶餘額->修改訂單狀態*簡單說:下訂單->扣庫存->減餘額->改狀態*/
@override
@GlobalTransactional(name = "zqh-create-order" ,rollbackFor = Exception.class)  //rollbackFor表示導致事務回滾的異常類陣列,name表示事務的名稱,具有唯一性
public void create(order order)
{
   Log.info("----->開始新建訂單");
   orderDao.create(order);

   Log.info("----->訂單微服務開始呼叫庫存,做扣減count" );
   storageservice.decrease(order.getProductId() ,order.getcount());

   Log.info("----->訂單微服務開始呼叫賬戶,做扣減Money" ) ; 
   accountservice.decrease(order.getuserId( ) ,order.getMoney());

   Log.info("----->訂單微服務開始修改訂單狀態"); 
   orderDao.update(order-getuserId(), status: 1);
   Log.info( "----->修改訂單狀態結束"); Log.info("----->下訂單結束了,o(n_n)o哈哈~");
}

三、Seata原理簡介

  Seata是2019年螞蟻金服和阿里巴巴共同開源的分散式事務解決方案,商用的時候要使用1.0以上,0.9版本不支援大規模叢集。在前面我們完成了簡單的微服務事務方案,其中增加了@GlobalTransactional註解的微服務就是TM,Seata伺服器就是TC,事務的參與方就是RM。

  在執行第一階段,Seata會攔截業務sql語句,解析sql語義,在資料操作前儲存之前的"before image"映象,執行操作後儲存"after image"映象,最後生成行鎖,這些操作全部在一個事務中完成。流程如下:

  第二階段,如果提交順利,Seata會將第一階段儲存的快照資料和行鎖刪除清空資料即可,反之則根據快照恢復全部資料到之前的狀態(在還原資料之前會校驗髒寫,檢查是否已被其他操作處理過,如果是則需要人工介入),然後再刪除快照和行鎖資料。流程如下: