一、LCN分布式事務(wù)控制原理
TX-LCN官網(wǎng):http://www.txlcn.org/zh-cn/
TX-LCN由兩大模塊組成:TM(TxManager)、TC(TxClient)。TM是全局事務(wù)協(xié)調(diào)者,TC為事務(wù)參與者(也包含事務(wù)發(fā)起者)。其事務(wù)的控制原理如下:
核心步驟:
1.事務(wù)發(fā)起者創(chuàng)建一個(gè)全局事物組group。
2.全局事務(wù)組通過(guò)Tracing(調(diào)用鏈子模塊)進(jìn)行服務(wù)間的全局?jǐn)?shù)據(jù)傳參。
3.其它參與者在調(diào)用鏈過(guò)程中加入到事務(wù)組
4.事務(wù)通知(各TC將事務(wù)狀態(tài)上報(bào)統(tǒng)一交由TM進(jìn)行管理)
5.TC響應(yīng)TM的事務(wù)通知(底層采用netty進(jìn)行通訊)
二、TM部署啟動(dòng)
1.maven引入tm,pom.xml配置
? ? <dependency>
? ? ? ? <groupId>com.codingapi.txlcn</groupId>
? ? ? ? <artifactId>txlcn-tm</artifactId>
? ? ? ? <version>5.0.2.RELEASE</version>
? ? </dependency>
? ? <dependency>
? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? <artifactId>spring-boot-starter-data-redis</artifactId>
? ? </dependency>
2.開(kāi)啟事務(wù)管理
在springboot啟動(dòng)類上加入注解@EnableTransactionManagerServer:
3.TM環(huán)境
創(chuàng)建數(shù)據(jù)表(t_tx_exception)
CREATE TABLE `t_tx_exception`? (
? `id` bigint(20) NOT NULL AUTO_INCREMENT,
? `group_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
? `unit_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
? `mod_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
? `transaction_state` tinyint(4) NULL DEFAULT NULL,
? `registrar` tinyint(4) NULL DEFAULT NULL,
? `remark` varchar(4096) NULL DEFAULT? NULL,
? `ex_state` tinyint(4) NULL DEFAULT NULL COMMENT '0 未解決 1已解決',
? `create_time` datetime(0) NULL DEFAULT NULL,
? PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
application.properties配置信息:
以下是推薦配置:
spring.application.name=tx-manager
server.port=7970
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.use-generated-keys=true
#tx-lcn.logger.enabled=true
# TxManager Host Ip
#tx-lcn.manager.host=127.0.0.1
# TxClient連接請(qǐng)求端口
#tx-lcn.manager.port=8070
# 心跳檢測(cè)時(shí)間(ms)
#tx-lcn.manager.heart-time=15000
# 分布式事務(wù)執(zhí)行總時(shí)間
#tx-lcn.manager.dtx-time=30000
#參數(shù)延遲刪除時(shí)間單位ms
#tx-lcn.message.netty.attr-delay-time=10000
#tx-lcn.manager.concurrent-level=128
# 開(kāi)啟日志
#tx-lcn.logger.enabled=true
#logging.level.com.codingapi=debug
#redis 主機(jī)
#spring.redis.host=127.0.0.1
#redis 端口
#spring.redis.port=6379
#redis 密碼
#spring.redis.password=
配置樣例:
TM啟動(dòng):
三、TM啟動(dòng)過(guò)程跟進(jìn)
tm可以獨(dú)立部署應(yīng)用為lcn服務(wù)端項(xiàng)目
1.@EnableTransactionManagerServer注解導(dǎo)入了TMAutoConfiguration自動(dòng)配置:
2.TMAutoConfiguration核心配置類:
3.TxLcnApplicationRunner實(shí)現(xiàn)了ApplicationRunner接口,springboot在IOC容器初始化過(guò)程中會(huì)自動(dòng)調(diào)用run方法:
4.initializers的初始化器的其中NettyRpcServerInitialize對(duì)TM啟動(dòng)開(kāi)啟了netty服務(wù)(客戶端TC連接的服務(wù)器)
啟動(dòng)netty服務(wù)默認(rèn)的ip/port是:127.0.0.1/8070
5.TMAutoCluster將TM實(shí)例信息存儲(chǔ)到Redis
四、TC部署啟動(dòng)
tc可以在你的任何一個(gè)獨(dú)立微服務(wù)項(xiàng)目中引入作為客戶端應(yīng)用。
1.pom.xml配置:
<dependency>
? ? <groupId>com.codingapi.txlcn</groupId>
? ? <artifactId>txlcn-tc</artifactId>
? ? <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
? ? <groupId>com.codingapi.txlcn</groupId>
? ? <artifactId>txlcn-txmsg-netty</artifactId>
? ? <version>5.0.2.RELEASE</version>
</dependency>
2.application.properties配置信息:
# 默認(rèn)之配置為TM的本機(jī)默認(rèn)端口
tx-lcn.client.manager-address=127.0.0.1:8070
3.啟動(dòng)類開(kāi)啟注解@EnableDistributedTransaction
五、開(kāi)始使用lcn分布式事務(wù)
使用事務(wù)的前提是接口本身開(kāi)啟了本地@Transactional事務(wù)(lcn不產(chǎn)生新事務(wù))
1.項(xiàng)目環(huán)境介紹:
微服務(wù)demo-a--->TestAController開(kāi)啟lcn事務(wù),往表my_test插入一條數(shù)據(jù)并調(diào)用demo-b微服務(wù)接口,調(diào)用demo-b以后打印1/0模擬錯(cuò)誤:
微服務(wù)demo-b--->TestBController開(kāi)啟lcn事物,往my_test出入一條數(shù)據(jù):
2.測(cè)試:
分別啟動(dòng)微服務(wù)demo-a、demo-b:
接口調(diào)用前數(shù)據(jù)庫(kù)表數(shù)據(jù):
接口調(diào)用:
微服務(wù)demo-b執(zhí)行了insert語(yǔ)句:
再查看數(shù)據(jù)庫(kù):
結(jié)果說(shuō)明了,lcn的事物產(chǎn)生了作用,對(duì)demo-b微服務(wù)進(jìn)行了回滾。
六、lcn調(diào)用過(guò)程跟進(jìn)
核心:事物攔截器、tracing調(diào)用鏈
lcn事物代理主要是通過(guò)TransactionAspect切面攔截實(shí)現(xiàn)的:
下面開(kāi)始跟進(jìn):
demo-a:事物發(fā)起方
先進(jìn)入SpringTracingApplier,獲取groupId
首次調(diào)用groupId為空,接下來(lái)進(jìn)入TransactionAspect攔截器開(kāi)始方法攔截,開(kāi)啟事物,并創(chuàng)建全局事務(wù)組:
隨機(jī)生成事物組ID(這塊可以優(yōu)化,建議采用雪花算法生成,確保全球唯一ID)
事物參數(shù)進(jìn)行封裝:
執(zhí)行本地業(yè)務(wù)邏輯:
resttemplate監(jiān)聽(tīng),將全局事物組加入http header(X-Group-ID,X-App-Map)中進(jìn)行下游微服務(wù)的傳遞
開(kāi)始進(jìn)入微服務(wù)demo-b(獲取demo-a傳遞的header參數(shù)),加入事務(wù)組:
本地事物狀態(tài)上傳TM:
本文介紹到這里就把lcn分布式事物的核心原理,并對(duì)核心源碼進(jìn)行了跟蹤,后續(xù)事物通知采用的是netty進(jìn)行通訊。