SprinrBoot整合Seata使用AT模式解決多數(shù)據(jù)源分布式事務(wù)

SprinrBoot整合Seata使用AT模式解決多數(shù)據(jù)源分布式事務(wù)

分布式事務(wù)場景:

1.應(yīng)用中使用多數(shù)據(jù)源颜说,跨多個數(shù)據(jù)庫

2.跨多個應(yīng)用進程

Seata是阿里巴巴開源的分布式事務(wù)中間件,以高效并且對業(yè)務(wù)0 侵入的方式汰聋,解決微服務(wù)場景下面臨的分布式事務(wù)問題脑沿。

Seata下載地址:https://github.com/seata/seata/releases

進入官網(wǎng)不會下載,請參考如下截圖:


1.下載Window版本后马僻,打開如圖所示

2.其中Context.txt配置如圖


service.vgroupMapping.default_tx_group=default
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1/:3306/nacos-mysql?useUnicode=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000

3.然后進入seata-server1.4.2\conf目錄中修改對應(yīng)的參數(shù)
image.png
4.開始編輯file.conf文件
5.配置seata-server-1.4.2/conf/registry.conf
6.下載Seata對應(yīng)的Mysql腳本:https://github.com/seata/seata/blob/develop/script/server/db/mysql.sql
下面還有Oracle數(shù)據(jù)庫的腳本,也可以前往Github獲得所有SQl腳本
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_status_gmt_modified` (`status` , `gmt_modified`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_status` (`status`),
    KEY `idx_branch_id` (`branch_id`),
    KEY `idx_xid_and_branch_id` (`xid` , `branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

CREATE TABLE IF NOT EXISTS `distributed_lock`
(
    `lock_key`       CHAR(20) NOT NULL,
    `lock_value`     VARCHAR(20) NOT NULL,
    `expire`         BIGINT,
    primary key (`lock_key`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);
7.如果是Oracle對應(yīng)的腳本如下:
創(chuàng)建名稱為seata的數(shù)據(jù)庫注服,字符集utf8mb4韭邓、排序規(guī)則utf8mb4_general_ci
nacos的配置首先要修改連接的數(shù)據(jù)庫,在oracle新建一個SEATA命名空間和用戶溶弟,并插入三張表(global_table,branch_table,lock_table)女淑,腳本如下
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE global_table
(
    xid                       VARCHAR2(128) NOT NULL,
    transaction_id            NUMBER(19),
    status                    NUMBER(3)     NOT NULL,
    application_id            VARCHAR2(32),
    transaction_service_group VARCHAR2(32),
    transaction_name          VARCHAR2(128),
    timeout                   NUMBER(10),
    begin_time                NUMBER(19),
    application_data          VARCHAR2(2000),
    gmt_create                TIMESTAMP(0),
    gmt_modified              TIMESTAMP(0),
    PRIMARY KEY (xid)
);

CREATE INDEX idx_gmt_modified_status ON global_table (gmt_modified, status);
CREATE INDEX idx_transaction_id ON global_table (transaction_id);

-- the table to store BranchSession data
CREATE TABLE branch_table
(
    branch_id         NUMBER(19)    NOT NULL,
    xid               VARCHAR2(128) NOT NULL,
    transaction_id    NUMBER(19),
    resource_group_id VARCHAR2(32),
    resource_id       VARCHAR2(256),
    branch_type       VARCHAR2(8),
    status            NUMBER(3),
    client_id         VARCHAR2(64),
    application_data  VARCHAR2(2000),
    gmt_create        TIMESTAMP(6),
    gmt_modified      TIMESTAMP(6),
    PRIMARY KEY (branch_id)
);

CREATE INDEX idx_xid ON branch_table (xid);

-- the table to store lock data
CREATE TABLE lock_table
(
    row_key        VARCHAR2(128) NOT NULL,
    xid            VARCHAR2(96),
    transaction_id NUMBER(19),
    branch_id      NUMBER(19)    NOT NULL,
    resource_id    VARCHAR2(256),
    table_name     VARCHAR2(32),
    pk             VARCHAR2(36),
    gmt_create     TIMESTAMP(0),
    gmt_modified   TIMESTAMP(0),
    PRIMARY KEY (row_key)
);

CREATE INDEX idx_branch_id ON lock_table (branch_id);
修改seata配置
store.db.dbType=oracle
# 這里是個坑OracleDriver并不存在在seata服務(wù)代碼里
store.db.driverClassName=oracle.jdbc.OracleDriver
store.db.url=jdbc:oracle:thin:@192.168.1.135:1521:helowin
store.db.user=SEATA
store.db.password=SEATA
8.業(yè)務(wù)數(shù)據(jù)庫中添加項目數(shù)據(jù)庫undo_log(就是你應(yīng)用平臺的數(shù)據(jù)庫)
和mysql一樣,項目數(shù)據(jù)庫也需要每個庫都加入undo_log表,腳本如下
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE undo_log
(
    id            NUMBER(19)    NOT NULL,
    branch_id     NUMBER(19)    NOT NULL,
    xid           VARCHAR2(100) NOT NULL,
    context       VARCHAR2(128) NOT NULL,
    rollback_info BLOB          NOT NULL,
    log_status    NUMBER(10)    NOT NULL,
    log_created   TIMESTAMP(0)  NOT NULL,
    log_modified  TIMESTAMP(0)  NOT NULL,
    PRIMARY KEY (id),
    CONSTRAINT ux_undo_log UNIQUE (xid, branch_id)
);

COMMENT ON TABLE undo_log IS 'AT transaction mode undo table';

-- Generate ID using sequence and trigger
CREATE SEQUENCE UNDO_LOG_SEQ START WITH 1 INCREMENT BY 1;
9.創(chuàng)建nacos-config.sh
內(nèi)容從Github鏈接nacos-config.sh中復(fù)制粘貼即可
10.然后再來看一下Seata的官方文檔
打開找到Nacos配置中心(Nacos是目前最主流的注冊中心)
執(zhí)行命令自動構(gòu)建Nacos配置
11.啟動Nacos創(chuàng)建一個命令空間如圖
12.初始化腳本數(shù)據(jù)到nacos
在執(zhí)行以下命令辜御,將配置自動加載到Nacos中
sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 此為上面的Nacos的Namespace的ID -u nacos -w nacos
然后查看Nacos中是否有配置
13.下載的Nacos中腳本下載說明

14.直接訪問在Github中獲取Seata中所需的文件

點擊 參考部署指南
到Github獲取sql腳本/各個配置中心參數(shù)導入腳本鸭你,config.txt/server端數(shù)據(jù)庫腳本
15.SpringBoot中添加配置
也可以參考官方文檔http://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html
點擊查看官方文檔
      <!--seata 分布式事務(wù)(使用這種方式可以自動傳遞xid)-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <version>2.2.0.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.4.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>druid</artifactId>
                    <groupId>com.alibaba</groupId>
                </exclusion>
            </exclusions>
        </dependency>

yaml應(yīng)用服務(wù)配置

seata: ## Seata分布式事務(wù)配置管理
  enabled: true
  enable-auto-data-source-proxy: true
  # seata 事務(wù)組編號 用于TC集群名  # 必須和config.txt里面配置的屬性一致
  tx-service-group: default_tx_group
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
  config:
    # 必須寫nacos,否則默認file
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      username: nacos
      password: nacos
      namespace: nacos的namespaced例如:65f556f2-1dc4-4b13-af44-6914f7f5bf73
  service:
    # 事務(wù)組對應(yīng)的集群名稱
    vgroup-mapping:
      default_tx_group: default
    disable-global-transaction: false
  client:
    rm:
      report-success-enable: false


15.如果以上都配置完畢擒权,就啟動Seata/應(yīng)用服務(wù)
BUG問題
can not get cluster name in registry config 
'service.vgroupMapping.account-service-fescar-service-group'
please make sure registry config correct
說明沒有配置正確袱巨,如下,必須保證 type 為 nacos碳抄,namespace愉老、group
也必須和 seata-server 注冊時的數(shù)據(jù)統(tǒng)一才可以
16.代碼應(yīng)用

17.官網(wǎng)示例參考
http://seata.io/zh-cn/docs/user/quickstart.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剖效,隨后出現(xiàn)的幾起案子嫉入,更是在濱河造成了極大的恐慌,老刑警劉巖璧尸,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咒林,死亡現(xiàn)場離奇詭異,居然都是意外死亡爷光,警方通過查閱死者的電腦和手機垫竞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛀序,“玉大人件甥,你說我怎么就攤上這事捌议。” “怎么了引有?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵瓣颅,是天一觀的道長。 經(jīng)常有香客問我譬正,道長宫补,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任曾我,我火速辦了婚禮粉怕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抒巢。我一直安慰自己贫贝,他們只是感情好,可當我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布蛉谜。 她就那樣靜靜地躺著稚晚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪型诚。 梳的紋絲不亂的頭發(fā)上客燕,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機與錄音狰贯,去河邊找鬼也搓。 笑死,一個胖子當著我的面吹牛涵紊,可吹牛的內(nèi)容都是我干的傍妒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼摸柄,長吁一口氣:“原來是場噩夢啊……” “哼拍顷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起塘幅,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤昔案,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后电媳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踏揣,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年匾乓,在試婚紗的時候發(fā)現(xiàn)自己被綠了捞稿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娱局,靈堂內(nèi)的尸體忽然破棺而出彰亥,到底是詐尸還是另有隱情,我是刑警寧澤衰齐,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布任斋,位于F島的核電站,受9級特大地震影響耻涛,放射性物質(zhì)發(fā)生泄漏废酷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一抹缕、第九天 我趴在偏房一處隱蔽的房頂上張望澈蟆。 院中可真熱鬧,春花似錦卓研、人聲如沸趴俘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寥闪。三九已至,卻和暖如春志珍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背垛叨。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工伦糯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嗽元。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓敛纲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親剂癌。 傳聞我的和親對象是個殘疾皇子淤翔,可洞房花燭夜當晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容