成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用Go輕松完成一個(gè)XA分布式事務(wù),保姆級(jí)教程

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

 [[423848]]

事務(wù)

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

  1. -- 從id=1的賬戶給id=2的賬戶轉(zhuǎn)賬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í)行,或者,由于某些原因,如果第一條語句成功,第二條語句失敗,就必須全部撤銷。

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

微服務(wù)

如果一個(gè)事務(wù)涉及的所有操作能夠放在一個(gè)服務(wù)內(nèi)部,那么使用各門語言里事務(wù)相關(guān)的庫,可以輕松的實(shí)現(xiàn)多個(gè)操作作為整體的事務(wù)操作。

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

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

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

分布式事務(wù)

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

分布式事務(wù)方案包括:

  • xa
  • tcc
  • saga
  • 可靠消息

下面我們看看最簡單的xa

XA

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

XA一共分為兩階段:

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

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

我們看看本地?cái)?shù)據(jù)庫是如何支持XA的:

第一階段 準(zhǔn)備

  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. -- 當(dāng)所有的參與者完成了prepare,就進(jìn)入第二階段 提交 
  6. xa commit '4fPqCNTYeSG' 

xa實(shí)踐

介紹了這么多,我們來實(shí)踐完成一個(gè)微服務(wù)上的xa事務(wù),加深分布式事務(wù)的理解,這里采用dtm作為分布式事務(wù)的管理者,來運(yùn)行其中一個(gè)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 

運(yùn)行示例

go run app/main.go xa

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

  1. # 服務(wù)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. # 服務(wù)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. # 服務(wù)1輸出 
  14. xa commit '4fPqCNTYeSG' 
  15.  
  16. #服務(wù)2輸出 
  17. xa commit '4fPqCPijxyC' 

整個(gè)交互的時(shí)序詳情如下

代碼如下:

  1. // 微服務(wù)的處理函數(shù): 
  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事務(wù) 
  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. }) 

總結(jié)

至此,一個(gè)完整的xa分布式事務(wù)介紹完成。

關(guān)于分布式事務(wù)更多更全面的知識(shí),請參考 分布式事務(wù)最經(jīng)典的七種解決方案

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

 

責(zé)任編輯:張燕妮 來源: Go語言中文網(wǎng)
相關(guān)推薦

2021-10-25 10:33:29

Python 開發(fā)編程語言

2021-10-11 09:24:14

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

2021-09-07 09:26:13

Python 開發(fā)編程語言

2022-06-27 08:36:27

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

2021-04-23 08:15:51

Seata XA AT

2021-12-09 10:45:19

分布式事務(wù)框架

2019-12-27 16:00:56

分布式事務(wù)框架Java

2020-04-28 12:18:08

Seata模式分布式

2021-12-15 10:00:21

分布式事務(wù)框架

2022-06-27 08:21:05

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

2022-09-29 08:28:57

SpringRedis分布式

2022-09-22 13:28:34

Redis分布式鎖

2017-07-26 15:08:05

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

2022-06-21 08:27:22

Seata分布式事務(wù)

2020-07-30 09:35:09

Redis分布式鎖數(shù)據(jù)庫

2019-10-10 09:16:34

Zookeeper架構(gòu)分布式

2017-09-04 14:46:10

分布式事務(wù)問題

2024-05-07 09:00:41

Go語言令牌桶

2009-06-19 15:28:31

JDBC分布式事務(wù)

2024-06-07 08:06:36

點(diǎn)贊
收藏

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

主站蜘蛛池模板: 成人国产精品 | 亚洲精品电影在线观看 | 久久日韩精品一区二区三区 | 欧美 日韩 中文 | 天堂色区| 亚洲日韩中文字幕一区 | 精精国产xxxx视频在线播放 | 国产不卡在线播放 | a免费视频 | 亚洲成人免费在线 | 成人在线观看免费观看 | 国产一区二区三区精品久久久 | 成人日韩 | 深爱激情综合 | 欧美一级久久 | 日韩视频一区 | 精品欧美一区二区三区久久久 | 亚洲欧美日韩国产 | 中文字字幕一区二区三区四区五区 | 日韩久久精品电影 | 欧美日韩在线一区二区 | 国产一区二区a | 免费在线一区二区 | 欧美精品一区二区在线观看 | 成人高清网站 | 国产精品视频一二三区 | 日韩有码在线观看 | 欧美视频一区二区三区 | 国产一区二区在线免费视频 | 久久精品免费 | 视频国产一区 | 久久成人在线视频 | 福利视频网站 | 国产精品国产精品国产专区不卡 | 欧美一级欧美一级在线播放 | 99精品网| 久久久久久久久久久一区二区 | 碰碰视频| 日本不卡免费新一二三区 | 国产在线精品一区二区 | 欧美嘿咻 |