10 【分布式事務(wù)----LCN】LCN原理及使用方式

一、簡介
LCN分布式事務(wù)框架其本身并不創(chuàng)建事務(wù),而是基于對本地事務(wù)的協(xié)調(diào)從而達到事務(wù)一致性的效果蜜另。

LCN5.0.2有3種模式,分別是LCN模式嫡意,TCC模式举瑰,TXC模式

LCN模式:

LCN模式是通過代理Connection的方式實現(xiàn)對本地事務(wù)的操作,然后在由TxManager統(tǒng)一協(xié)調(diào)控制事務(wù)蔬螟。當本地事務(wù)提交回滾或者關(guān)閉連接時將會執(zhí)行假操作此迅,該代理的連接將由LCN連接池管理。
該模式的特點:

  • 該模式對代碼的嵌入性為低旧巾。
  • 該模式僅限于本地存在連接對象且可通過連接對象控制事務(wù)的模塊耸序。
  • 該模式下的事務(wù)提交與回滾是由本地事務(wù)方控制,對于數(shù)據(jù)一致性上有較高的保障鲁猩。
  • 該模式缺陷在于代理的連接需要隨事務(wù)發(fā)起方一共釋放連接坎怪,增加了連接占用的時間。

TCC模式:

TCC事務(wù)機制相對于傳統(tǒng)事務(wù)機制(X/Open XA Two-Phase-Commit)廓握,其特征在于它不依賴資源管理器(RM)對XA的支持搅窿,而是通過對(由業(yè)務(wù)系統(tǒng)提供的)業(yè)務(wù)邏輯的調(diào)度來實現(xiàn)分布式事務(wù)。主要由三步操作隙券,Try: 嘗試執(zhí)行業(yè)務(wù)男应、 Confirm:確認執(zhí)行業(yè)務(wù)、 Cancel: 取消執(zhí)行業(yè)務(wù)娱仔。

該模式的特點:

  • 該模式對代碼的嵌入性高沐飘,要求每個業(yè)務(wù)需要寫三種步驟的操作。
  • 該模式對有無本地事務(wù)控制都可以支持使用面廣牲迫。
  • 數(shù)據(jù)一致性控制幾乎完全由開發(fā)者控制薪铜,對業(yè)務(wù)開發(fā)難度要求高众弓。

TXC模式:
TXC模式命名來源于淘寶恩溅,實現(xiàn)原理是在執(zhí)行SQL之前隔箍,先查詢SQL的影響數(shù)據(jù),然后保存執(zhí)行的SQL快走信息和創(chuàng)建鎖脚乡。當需要回滾的時候就采用這些記錄數(shù)據(jù)回滾數(shù)據(jù)庫蜒滩,目前鎖實現(xiàn)依賴redis分布式鎖控制。
該模式的特點:

  • 該模式同樣對代碼的嵌入性低奶稠。
  • 該模式僅限于對支持SQL方式的模塊支持俯艰。
  • 該模式由于每次執(zhí)行SQL之前需要先查詢影響數(shù)據(jù),因此相比LCN模式消耗資源與時間要多锌订。
  • 該模式不會占用數(shù)據(jù)庫的連接資源竹握。
    二、原理
    核心步驟
    1.創(chuàng)建事務(wù)組
    是指在事務(wù)發(fā)起方開始執(zhí)行業(yè)務(wù)代碼之前先調(diào)用TxManager創(chuàng)建事務(wù)組對象辆飘,然后拿到事務(wù)標示GroupId的過程啦辐。
    2.添加事務(wù)組
    添加事務(wù)組是指參與方在執(zhí)行完業(yè)務(wù)方法以后,將該模塊的事務(wù)信息添加通知給TxManager的操作蜈项。
    3.關(guān)閉事務(wù)組
    是指在發(fā)起方執(zhí)行完業(yè)務(wù)代碼以后芹关,將發(fā)起方執(zhí)行結(jié)果狀態(tài)通知給TxManager的動作。當執(zhí)行完關(guān)閉事務(wù)組的方法以后紧卒,TxManager將根據(jù)事務(wù)組信息來通知相應(yīng)的參與模塊提交或回滾事務(wù)侥衬。

事務(wù)控制原理

LCN事務(wù)控制原理是由事務(wù)模塊TxClient下的代理連接池與TxManager的協(xié)調(diào)配合完成的事務(wù)協(xié)調(diào)控制。

TxClient的代理連接池實現(xiàn)了javax.sql.DataSource接口跑芳,并重寫了close方法轴总,事務(wù)模塊在提交關(guān)閉以后TxClient連接池將執(zhí)行"假關(guān)閉"操作,等待TxManager協(xié)調(diào)完成事務(wù)以后在關(guān)閉連接博个。

對于代理連接池的優(yōu)化
自動超時機制怀樟,任何通訊都有最大超時限制,參與模塊在等待通知的狀態(tài)下也有最大超時限制坡倔,當超過時間限制以后事務(wù)模塊將先確認事務(wù)狀態(tài)漂佩,然后再決定執(zhí)行提交或者回滾操作,主要為了給最大資源占用時間加上限制罪塔。
智能識別創(chuàng)建不同的連接 對于只讀操作投蝉、非事務(wù)操作LCN將不開啟代理功能,返回本地連接對象征堪,對于補償事務(wù)的啟動方將開啟回滾連接對象瘩缆,執(zhí)行完業(yè)務(wù)以后馬上回滾事務(wù)。
LCN連接重用機制 當模塊在同一次事務(wù)下被重復執(zhí)行時佃蚜,連接資源會被重用庸娱,提高連接的使用率着绊。

事務(wù)補償機制
為什么需要事務(wù)補償?

事務(wù)補償是指在執(zhí)行某個業(yè)務(wù)方法時熟尉,本應(yīng)該執(zhí)行成功的操作卻因為服務(wù)器掛機或者網(wǎng)絡(luò)抖動等問題導致事務(wù)沒有正常提交归露,此種場景就需要通過補償來完成事務(wù),從而達到事務(wù)的一致性斤儿。

補償機制的觸發(fā)條件剧包?

當執(zhí)行關(guān)閉事務(wù)組步驟時,若發(fā)起方接受到失敗的狀態(tài)后將會把該次事務(wù)識別為待補償事務(wù)往果,然后發(fā)起方將該次事務(wù)數(shù)據(jù)異步通知給TxManager疆液。TxManager接受到補償事務(wù)以后先通知補償回調(diào)地址,然后再根據(jù)是否開啟自動補償事務(wù)狀態(tài)來補償或保存該次切面事務(wù)數(shù)據(jù)陕贮。

補償事務(wù)機制堕油?
LCN的補償事務(wù)原理是模擬上次失敗事務(wù)的請求,然后傳遞給TxClient模塊然后再次執(zhí)行該次請求事務(wù)肮之。

模擬場景演示
若存在事務(wù)發(fā)起方掉缺、參與方A、參與方B局骤。調(diào)用關(guān)系圖如下

那么他們正常執(zhí)行業(yè)務(wù)的時序圖為:

若參與方B出現(xiàn)異常攀圈,那么他們的業(yè)務(wù)時序圖為:

若他們的調(diào)用關(guān)系是這樣的情況

此時發(fā)生參與方B出現(xiàn)異常時他們的時序圖為:

三、使用
環(huán)境:

SpringBoot 2.0.4
SpringCloud(Eureka+Gateway) Finchley.SR3
MySQL 5.7
Redis
LCN5.0.2
準備:

3.1搭建好Redis和MySQL
SQL建表語句(在txlcn-tm模塊的resource目錄下)

/*
Navicat Premium Data Transfer
Source Server : local
Source Server Type : MySQL
Source Server Version : 100309
Source Host : localhost:3306
Source Schema : tx-manager
Target Server Type : MySQL
Target Server Version : 100309
File Encoding : 65001
Date: 29/12/2018 18:35:59
*/
CREATE DATABASE IF NOT EXISTS tx-manager DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
USE tx-manager;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;


-- Table structure for t_tx_exception


DROP TABLE IF EXISTS 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,
ex_state tinyint(4) NULL DEFAULT NULL COMMENT '0 待處理 1已處理',
remark varchar(10240) NULL DEFAULT NULL COMMENT '備注',
create_time datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 967 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
3.2下載源碼并編譯
源碼下載地址:https://github.com/codingapi/tx-lcn

工程目錄

修改txlcn-tm的配置文件application.properties

####################### 服務(wù) ############################################

spring.application.name=TransactionManager
server.port=7970

####################### 數(shù)據(jù)庫 ############################################
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://47.92.145.192:3306/scm_transaction?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
spring.datasource.username=db_user2
spring.datasource.password=db_pass

驗證連接是否有效峦甩。此參數(shù)必須設(shè)置為非空字符串赘来,下面三項設(shè)置成true才能生

spring.datasource.validationQuery=SELECT 1

指明連接是否被空閑連接回收器(如果有)進行檢驗.如果檢測失敗,則連接將被從池中去除.

spring.datasource.testWhileIdle=true

指明是否在從池中取出連接前進行檢驗,如果檢驗失敗,則從池中去除連接并嘗試取出另一個

spring.datasource.testOnBorrow=true

指明是否在歸還到池中前進行檢驗

spring.datasource.testOnReturn=false

以下可省略

初始化大小,最小凯傲,最大

spring.datasource.initialSize=5
spring.datasource.minIdle=10
spring.datasource.maxActive=1000

配置獲取連接等待超時的時間

spring.datasource.maxWait=60000

配置間隔多久才進行一次檢測犬辰,檢測需要關(guān)閉的空閑連接,單位是毫秒

spring.datasource.timeBetweenEvictionRunsMillis=60000

配置一個連接在池中最小生存的時間冰单,單位是毫秒

spring.datasource.minEvictableIdleTimeMillis=300000

打開PSCache幌缝,并且指定每個連接上PSCache的大小

spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20

配置監(jiān)控統(tǒng)計攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計诫欠,'wall'用于防火墻

spring.datasource.filters=stat,wall,log4j

通過connectProperties屬性來打開mergeSql功能涵卵;慢SQL記錄

spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000;druid.stat.logSlowSql=true

合并多個DruidDataSource的監(jiān)控數(shù)據(jù)

spring.datasource.useGlobalDataSourceStat=true

spring.datasource.WebStatFilter.exclusions=".js,.gif,.jpg,.png,.css,.ico,/druid/*"

spring.datasource.stat-view-servlet.login-username=admin

spring.datasource.stat-view-servlet.login-password=admin

####################### 數(shù)據(jù)庫方言 ############################################
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

第一次運行可以設(shè)置為: create, 為TM創(chuàng)建持久化數(shù)據(jù)庫表

spring.jpa.hibernate.ddl-auto=update

####################### Redis ############################################
spring.redis.host=47.92.145.192
spring.redis.port=6379
spring.redis.password=WZTH@dev123

####################### 事務(wù) ############################################

TM監(jiān)聽IP. 默認為 127.0.0.1

tx-lcn.manager.host=127.0.0.1

TM監(jiān)聽Socket端口. 默認為 ${server.port} - 100

tx-lcn.manager.port=8070

心跳檢測時間(ms). 默認為 300000

tx-lcn.manager.heart-time=300000

分布式事務(wù)執(zhí)行總時間(ms). 默認為36000

tx-lcn.manager.dtx-time=8000

參數(shù)延遲刪除時間單位ms 默認為dtx-time值

tx-lcn.message.netty.attr-delay-time=${tx-lcn.manager.dtx-time}

事務(wù)處理并發(fā)等級. 默認為機器邏輯核心數(shù)5倍

tx-lcn.manager.concurrent-level=160

TM后臺登陸密碼,默認值為codingapi

tx-lcn.manager.admin-key=123456

分布式事務(wù)鎖超時時間 默認為-1荒叼,當-1時會用tx-lcn.manager.dtx-time的時間

tx-lcn.manager.dtx-lock-time=${tx-lcn.manager.dtx-time}

雪花算法的sequence位長度轿偎,默認為12位.

tx-lcn.manager.seq-len=12

異常回調(diào)開關(guān)被廓。開啟時請制定ex-url

tx-lcn.manager.ex-url-enabled=false

事務(wù)異常通知(任何http協(xié)議地址坏晦。未指定協(xié)議時,為TM提供內(nèi)置功能接口)。默認是郵件通知

tx-lcn.manager.ex-url=/provider/email-to/306509906@qq.com
注意:個人修改了數(shù)據(jù)庫的名稱昆婿,和用戶名密碼球碉,根據(jù)自己的實際情況修改

txlcn-tm的pom修改,放開配置

注掉配置

最后使用maven編譯仓蛆,去掉test睁冬,否則編譯很慢

3.3啟動txlcn-tm模塊
不知道怎么啟動的可以自行查閱Springboot運行方式

啟動后打開后臺地址http://localhost:7970,初始密碼是codingapi多律,我這里改成了123456

登陸后

3.4項目配置
pom引用

        <!-- LCN -->
        <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>
        <dependency>
            <groupId>com.codingapi.txlcn</groupId>
            <artifactId>txlcn-tm</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

配置文件增加事務(wù)管理中心地址

LCN

tx-lcn:
client:
manager-address: 127.0.0.1:8070
logger:
enabled: true

driver-class-name: com.mysql.jdbc.Driver

jdbc-url: jdbc:mysql://47.92.145.192:3306/scm_transaction?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false

username: db_user2

password: db_pass

Consumer痴突、Provider1、Provider2啟動類增加注解

@EnableDistributedTransaction // 啟用分布式事務(wù)
在Priovider1狼荞、Provider2要執(zhí)行的方法上增加注解

@LcnTransaction //分布式事務(wù)注解
@Transactional //本地事務(wù)注解
最后運行 驗證即可

原文鏈接:https://blog.csdn.net/ningjiebing/java/article/details/89948050

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市帮碰,隨后出現(xiàn)的幾起案子相味,更是在濱河造成了極大的恐慌,老刑警劉巖殉挽,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丰涉,死亡現(xiàn)場離奇詭異,居然都是意外死亡斯碌,警方通過查閱死者的電腦和手機一死,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來傻唾,“玉大人投慈,你說我怎么就攤上這事」诮荆” “怎么了伪煤?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長凛辣。 經(jīng)常有香客問我抱既,道長,這世上最難降的妖魔是什么扁誓? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任防泵,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘指攒。我一直安慰自己幻捏,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布肚邢。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骡湖。 梳的紋絲不亂的頭發(fā)上贱纠,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音响蕴,去河邊找鬼谆焊。 笑死,一個胖子當著我的面吹牛浦夷,可吹牛的內(nèi)容都是我干的辖试。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼劈狐,長吁一口氣:“原來是場噩夢啊……” “哼罐孝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起肥缔,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤莲兢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后续膳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體改艇,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年坟岔,在試婚紗的時候發(fā)現(xiàn)自己被綠了谒兄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡社付,死狀恐怖承疲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瘦穆,我是刑警寧澤纪隙,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站扛或,受9級特大地震影響绵咱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜熙兔,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一悲伶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧住涉,春花似錦麸锉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柳爽。三九已至,卻和暖如春碱屁,著一層夾襖步出監(jiān)牢的瞬間磷脯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工娩脾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赵誓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓柿赊,卻偏偏與公主長得像俩功,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子碰声,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355