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

用Go輕松完成一個XA分布式事務,保姆級教程

開發(fā) 前端 分布式
如果一個事務涉及的所有操作能夠放在一個服務內部,那么使用各門語言里事務相關的庫,可以輕松的實現多個操作作為整體的事務操作。

 [[423848]]

事務

某些業(yè)務要求,一系列操作必須全部執(zhí)行,而不能僅執(zhí)行一部分。例如,一個轉賬操作:

  1. -- 從id=1的賬戶給id=2的賬戶轉賬100元 
  2. -- 第一步:將id=1的A賬戶余額減去100 
  3. UPDATE accounts SET balance = balance - 100 WHERE id = 1
  4. -- 第二步:將id=2的B賬戶余額加上100 
  5. UPDATE accounts SET balance = balance + 100 WHERE id = 2

這兩條SQL語句必須全部執(zhí)行,或者,由于某些原因,如果第一條語句成功,第二條語句失敗,就必須全部撤銷。

這種把多條語句作為一個整體進行操作的功能,被稱為數據庫事務。數據庫事務可以確保該事務范圍內的所有操作都可以全部 成功或者全部失敗。如果事務失敗,那么效果就和沒有執(zhí)行這些SQL一樣,不會對數據庫數據有任何改動。

微服務

如果一個事務涉及的所有操作能夠放在一個服務內部,那么使用各門語言里事務相關的庫,可以輕松的實現多個操作作為整體的事務操作。

但是有些服務,例如生成訂單涉及做很多操作,包括庫存、優(yōu)惠券、贈送、賬戶余額等。當系統(tǒng)復雜程度增加時,想要把所有這些操作放到一個服務內實現,會導致耦合度太高,維護成本非常高。

針對復雜的系統(tǒng),當前流行的微服務架構是非常好的解決方案,該架構能夠把復雜系統(tǒng)進行拆分,拆分后形成了大量微服務,獨立開發(fā),獨立維護。

雖然服務拆分了,但是訂單本身的邏輯需要多個操作作為一個整體,要么全部成功,要么全部失敗,這就帶來了新的挑戰(zhàn)。如何把散落在各個微服務中的本地事務,組成一個大的事務,保證他們作為一個整體,這就是分布式事務需要解決的問題。

分布式事務

分布式事務簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分布在不同的服務器上,且屬于不同的應用,分布式事務需要保證這些小操作要么全部成功,要么全部失敗。本質上來說,分布式事務就是為了保證不同數據庫的數據一致性。

分布式事務方案包括:

  • xa
  • tcc
  • saga
  • 可靠消息

下面我們看看最簡單的xa

XA

XA是由X/Open組織提出的分布式事務的規(guī)范,XA規(guī)范主要定義了(全局)事務管理器(TM)和(局部)資源管理器(RM)之間的接口。本地的數據庫如mysql在XA中扮演的是RM角色

XA一共分為兩階段:

第一階段(prepare):即所有的參與者RM準備執(zhí)行事務并鎖住需要的資源。參與者ready時,向TM報告已準備就緒。 第二階段 (commit/rollback):當事務管理者(TM)確認所有參與者(RM)都ready后,向所有參與者發(fā)送commit命令。

目前主流的數據庫基本都支持XA事務,包括mysql、oracle、sqlserver、postgre

我們看看本地數據庫是如何支持XA的:

第一階段 準備

  1. XA start '4fPqCNTYeSG' 
  2. UPDATE `user_account` SET `balance`=balance + 30,`update_time`='2021-06-09 11:50:42.438' WHERE user_id = '1' 
  3. XA end '4fPqCNTYeSG' 
  4. XA prepare '4fPqCNTYeSG' 
  5. -- 當所有的參與者完成了prepare,就進入第二階段 提交 
  6. xa commit '4fPqCNTYeSG' 

xa實踐

介紹了這么多,我們來實踐完成一個微服務上的xa事務,加深分布式事務的理解,這里采用dtm作為分布式事務的管理者,來運行其中一個xa的demo

安裝go 安裝mysql

獲取dtm

  1. git clone https://github.com/yedf/dtm.git 
  2. cd dtm 

配置mysql

  1. cp conf.sample.yml conf.yml 
  2. vi conf.yml 

運行示例

go run app/main.go xa

從日志里,能夠找到XA部分的輸出,最后成功提交完成了事務

  1. # 服務1輸出 
  2. XA start '4fPqCNTYeSG' 
  3. UPDATE `user_account` SET `balance`=balance - 30,`update_time`='2021-06-09 11:50:42.438' WHERE user_id = '1' 
  4. XA end '4fPqCNTYeSG' 
  5. XA prepare '4fPqCNTYeSG' 
  6.  
  7. # 服務2輸出 
  8. XA start '4fPqCPijxyC' 
  9. UPDATE `user_account` SET `balance`=balance + 30,`update_time`='2021-06-09 11:50:42.493' WHERE user_id = '2' 
  10. XA end '4fPqCPijxyC' 
  11. XA prepare '4fPqCPijxyC' 
  12.  
  13. # 服務1輸出 
  14. xa commit '4fPqCNTYeSG' 
  15.  
  16. #服務2輸出 
  17. xa commit '4fPqCPijxyC' 

整個交互的時序詳情如下

代碼如下:

  1. // 微服務的處理函數: 
  2. app.POST(BusiAPI+"/TransInXa", common.WrapHandler(func(c *gin.Context) (interface{}, error) { 
  3.     return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) (interface{}, error) { 
  4.         _, err := dtmcli.DBExec(db, "update dtm_busi.user_account set balance=balance+? where user_id=?", reqFrom(c).Amount, 2
  5.         return dtmcli.MapSuccess, err 
  6.     }) 
  7. })) 
  8. app.POST(BusiAPI+"/TransOutXa", common.WrapHandler(func(c *gin.Context) (interface{}, error) { 
  9.     return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) (interface{}, error) { 
  10.         _, err := dtmcli.DBExec(db, "update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, 1
  11.         return dtmcli.MapSuccess, err 
  12.     }) 
  13. })) 
  14.  
  15. // 開啟XA事務 
  16. err := XaClient.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { 
  17.     resp, err := xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOutXa"
  18.     if err != nil { 
  19.         return resp, err 
  20.     } 
  21.     return xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInXa"
  22. }) 

總結

至此,一個完整的xa分布式事務介紹完成。

關于分布式事務更多更全面的知識,請參考 分布式事務最經典的七種解決方案

在這篇簡短的文章里,我們大致介紹了 事務,分布式事務,微服務處理XA事務。有興趣的同學可以通過 dtm 繼續(xù)研究分布式事務。

 

責任編輯:張燕妮 來源: Go語言中文網
相關推薦

2021-10-25 10:33:29

Python 開發(fā)編程語言

2021-10-11 09:24:14

分布式架構系統(tǒng)

2021-09-07 09:26:13

Python 開發(fā)編程語言

2021-04-23 08:15:51

Seata XA AT

2022-06-27 08:36:27

分布式事務XA規(guī)范

2021-12-09 10:45:19

分布式事務框架

2020-04-28 12:18:08

Seata模式分布式

2019-12-27 16:00:56

分布式事務框架Java

2021-12-15 10:00:21

分布式事務框架

2022-06-27 08:21:05

Seata分布式事務微服務

2022-06-21 08:27:22

Seata分布式事務

2022-09-29 08:28:57

SpringRedis分布式

2022-09-22 13:28:34

Redis分布式鎖

2017-07-26 15:08:05

大數據分布式事務

2017-09-04 14:46:10

分布式事務問題

2020-07-30 09:35:09

Redis分布式鎖數據庫

2024-05-07 09:00:41

Go語言令牌桶

2019-10-10 09:16:34

Zookeeper架構分布式

2009-06-19 15:28:31

JDBC分布式事務

2021-11-05 07:18:15

分布式事務業(yè)務
點贊
收藏

51CTO技術棧公眾號