聽說(shuō) 你還不會(huì)SpringCloud分布式事務(wù)?
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
66套java從入門到精通實(shí)戰(zhàn)課程分享
一、基于XA的兩階段提交方案
兩階段提交方案應(yīng)用非常廣泛,幾乎所有商業(yè)OLTP數(shù)據(jù)庫(kù)都支持XA協(xié)議。但是兩階段提交方案鎖定資源時(shí)間長(zhǎng),對(duì)性能影響很大,基本不適合解決微服務(wù)事務(wù)問(wèn)題。
二、TCC解決方案
TCC方案在電商、金融領(lǐng)域落地較多。TCC方案其實(shí)是兩階段提交的一種改進(jìn)。其將整個(gè)業(yè)務(wù)邏輯的每個(gè)分支顯式的分成了Try、Confirm、Cancel三個(gè)操作。Try部分完成業(yè)務(wù)的準(zhǔn)備工作,confirm部分完成業(yè)務(wù)的提交,cancel部分完成事務(wù)的回滾。基本原理如下圖所示。
事務(wù)開始時(shí),業(yè)務(wù)應(yīng)用會(huì)向事務(wù)協(xié)調(diào)器注冊(cè)啟動(dòng)事務(wù)。之后業(yè)務(wù)應(yīng)用會(huì)調(diào)用所有服務(wù)的try接口,完成一階段準(zhǔn)備。之后事務(wù)協(xié)調(diào)器會(huì)根據(jù)try接口返回情況,決定調(diào)用confirm接口或者cancel接口。如果接口調(diào)用失敗,會(huì)進(jìn)行重試。
微服務(wù)倡導(dǎo)服務(wù)的輕量化、易部署,而TCC方案中很多事務(wù)的處理邏輯需要應(yīng)用自己編碼實(shí)現(xiàn),復(fù)雜且開發(fā)量大。

三、分布式事務(wù)中間件解決方案
分布式事務(wù)中間件其本身并不創(chuàng)建事務(wù),而是基于對(duì)本地事務(wù)的協(xié)調(diào)從而達(dá)到事務(wù)一致性的效果。典型代表有:阿里的GTS(https://www.aliyun.com/aliware/txc)、開源應(yīng)用LCN。
其實(shí)現(xiàn)原理如下
LCN分布式事務(wù)框架
a. 在設(shè)計(jì)框架之初的1.0 ~ 2.0的版本時(shí),框架設(shè)計(jì)的步驟是如下的,各取其首字母得來(lái)的LCN命名。鎖定事務(wù)單元(lock)、確認(rèn)事務(wù)模塊狀態(tài)(confirm)、通知事務(wù)(notify)
b. 創(chuàng)建事務(wù)組:是指在事務(wù)發(fā)起方開始執(zhí)行業(yè)務(wù)代碼之前先調(diào)用TxManager創(chuàng)建事務(wù)組對(duì)象,然后拿到事務(wù)標(biāo)示GroupId的過(guò)程。
c. 添加事務(wù)組:添加事務(wù)組是指參與方在執(zhí)行完業(yè)務(wù)方法以后,將該模塊的事務(wù)信息添加通知給TxManager的操作。
d. 關(guān)閉事務(wù)組:是指在發(fā)起方執(zhí)行完業(yè)務(wù)代碼以后,將發(fā)起方執(zhí)行結(jié)果狀態(tài)通知給TxManager的動(dòng)作。當(dāng)執(zhí)行完關(guān)閉事務(wù)組的方法以后,TxManager將根據(jù)事務(wù)組信息來(lái)通知相應(yīng)的參與模塊提交或回滾事務(wù)
tx-lcn官方地址:https://www.txlcn.org/
tx-lcn Github地址:https://github.com/codingapi/tx-lcn
tx-lcn服務(wù)下載地址:https://pan.baidu.com/s/1cLKAeE#list/path=%2F
tx-lcn服務(wù)源碼地址:https://github.com/codingapi/tx-lcn/tree/master/tx-manager
LCN應(yīng)用 - 搭建tx-manager服務(wù)
LCN是通過(guò)一個(gè)獨(dú)立的微服務(wù)tx-manager作為分布式事務(wù)控制服務(wù)端(事務(wù)協(xié)調(diào)器)。需要執(zhí)行分布式事務(wù)控制的微服務(wù)應(yīng)用都通過(guò)遠(yuǎn)程服務(wù)調(diào)用的方式,在tx-manager上標(biāo)記事務(wù)組,在執(zhí)行事務(wù)處理后,將本地事務(wù)狀態(tài)發(fā)送到tx-manager中對(duì)應(yīng)的事務(wù)組上,tx-manager會(huì)根據(jù)具體的狀態(tài)來(lái)通知相應(yīng)的微服務(wù)應(yīng)用提交或回滾。
tx-manager也是使用Spring Cloud開發(fā)的一個(gè)微服務(wù)應(yīng)用,在搭建過(guò)程上是非常簡(jiǎn)單的。
下載tx-manager事務(wù)協(xié)調(diào)器zip壓縮包:https://pan.baidu.com/s/1cLKAeE#list/path=%2F
壓縮包解壓后內(nèi)容如下
修改application.properties配置文件,提供本地微服務(wù)應(yīng)用的Eureka注冊(cè)中心配置、redis配置。其中redis是事務(wù)協(xié)調(diào)器在處理事務(wù)組時(shí)使用的臨時(shí)存儲(chǔ)
##########################txmanager-start#######################
#服務(wù)端口
server.port=8899
#tx-manager不得修改
spring.application.name=tx-manager
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/static/
###########################txmanager-end#######################
#eureka?地址
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka/
eureka.instance.prefer-ip-address=true
#############################redis-start#########################
##redis?單點(diǎn)環(huán)境配置
#redis
spring.redis.database=0
spring.redis.timeout=0
spring.redis.host=192.168.1.136
spring.redis.port=6379
spring.redis.pool.max-active=100
spring.redis.pool.max-wait=3000
spring.redis.pool.max-idle=200
spring.redis.pool.min-idle=50
spring.redis.pool.timeout=600
##############################redis-end##########################
###############################LCN-start########################
tm.transaction.netty.delaytime?=?5
tm.transaction.netty.hearttime?=?15
tm.redis.savemaxtime=30
tm.socket.port=9999
tm.socket.maxconnection=100
tm.compensate.auto=false
tm.compensate.notifyUrl=http://ip:port/path
tm.compensate.tryTime=30
tm.compensate.maxWaitTime=5000
logging.level.com.codingapi=debug
將修改后的application.properties配置文件打包到tx-manager-x.x.x.jar中,替代jar中原有的默認(rèn)配置文件。
使用命令:java -jar tx-manager-x.x.x.jar啟動(dòng)微服務(wù)。
測(cè)試tx-manager事務(wù)協(xié)調(diào)器是否啟動(dòng)成功可以訪問(wèn)http://ip:8899/。如下結(jié)果代表事務(wù)協(xié)調(diào)器啟動(dòng)成功
在微服務(wù)中使用LCN實(shí)現(xiàn)分布式事務(wù)管理
在所有需要處理分布式事務(wù)的微服務(wù)中增加下述依賴:為統(tǒng)一資源版本,使用properties統(tǒng)一管理版本信息
?
??4.1.0
?
??
???com.codingapi
???transaction-springcloud
???${lcn.last.version}
???
????
?????org.slf4j
?????*
????
???
??
??
???com.codingapi
???tx-plugins-db
???${lcn.last.version}
???
????
?????org.slf4j
?????*
????
???
??
在全局配置文件中增加下述配置
#?定義事務(wù)協(xié)調(diào)器所在位置。根據(jù)具體環(huán)境定義其中的IP地址和端口。
tm.manager.url=http://127.0.0.1:8899/tx/manager/
使用LCN做分布式事務(wù)管理時(shí),微服務(wù)應(yīng)用內(nèi)必須提供一個(gè)用于獲取txUrl(txUrl就是全局配置文件中定義的tm.manager.url)的類型實(shí)現(xiàn),這個(gè)類可以使用獨(dú)立應(yīng)用定義,在微服務(wù)應(yīng)用中引入。本案例中為了方便,直接在所有的微服務(wù)應(yīng)用中提供對(duì)應(yīng)代碼實(shí)現(xiàn)。具體如下
@Service
public?class?TxManagerTxUrlServiceImpl?implements?TxManagerTxUrlService?{
?@Value("${tm.manager.url}")
?private?String?url;
?@Override
?public?String?getTxUrl()?{
??return?url;
?}
}
在分布式事務(wù)管理代碼中增加注解@TxTransaction。在業(yè)務(wù)調(diào)用方增加的注解需要屬性isStart=true。而被調(diào)用方則不需要定義任何的注解屬性。如:
交易服務(wù)調(diào)用了訂單服務(wù),那么交易服務(wù)中代碼
@TxTransaction(isStart=true)
@Transactional
public?void?trade()?{
????//本地調(diào)用
????tradeDao.save();
????//遠(yuǎn)程調(diào)用方
????orderService.order();
}
訂單服務(wù)中代碼
@Transactional
@TxTransaction
public?void?order()?{
????//本地調(diào)用
????orderDao.save();
}
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
本文鏈接:
https://blog.csdn.net/zhangningkid/article/details/99435037
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
???

?長(zhǎng)按上方微信二維碼?2 秒
感謝點(diǎn)贊支持下哈?




