分布式事務解決方案--seata AT模式(spring cloud eureka+fegin+seata)

一.整體搭建準備

? ?一.1.下載seata-server服務端(地址:https://seata.io/zh-cn/blog/download.html

? ? 一.2. 修改seata-serve里面的配置file.conf文件,file.conf.example文件,以及registry.conf文件

? ? 一.3. 從githhub下載好準備好的demo,然后配更改好demo里的一些配置文件(改成自己本地的即可)

? ? ? ? ? ? demo地址(https://github.com/chengshugithub/springcloud-eureka-feign-seata)

? ? 一.4. 運行 eureka的服務端,然后運行seata-server,然后繼續運行我們demo里面的三個服務;

二.先通過官網下載 seata-server(地址:https://seata.io/zh-cn/blog/download.html

? ?二.1.下載之后,我們進行解壓然后找到如下圖三個文件進行修改


?我的file.conf文件配置

這里我采用的是db方式,連接是mysql;自己改成自己本機的mysql的用戶名密碼和驅動

## transaction log store, only used in seata-server

store {

? ## store mode: file、db、redis

?#這里的話選擇是db,級尋找下面的db配置,這里我用的是mysql;

? mode = "db"

? ## file store property

? file {

? ? ## store location dir

? ? dir = "sessionStore"

? ? # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions

? ? maxBranchSessionSize = 16384

? ? # globe session size , if exceeded throws exceptions

? ? maxGlobalSessionSize = 512

? ? # file buffer size , if exceeded allocate new buffer

? ? fileWriteBufferCacheSize = 16384

? ? # when recover batch read size

? ? sessionReloadReadSize = 100

? ? # async, sync

? ? flushDiskMode = async

? }

? ## database store property

? db {

? ? ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.

? ? datasource = "dbcp"

? ? ## mysql/oracle/postgresql/h2/oceanbase etc.

? ? dbType = "mysql"

? ? driverClassName = "com.mysql.cj.jdbc.Driver"

? ? url = "jdbc:mysql://127.0.0.1:3306/seata-server?serverTimezone=GMT%2B8"

? ? user = "root"

? ? password = "root"

? ? minConn = 5

? ? maxConn = 100

? ? globalTable = "global_table"

? ? branchTable = "branch_table"

? ? lockTable = "lock_table"

? ? queryLimit = 100

? ? maxWait = 5000

? }

? ## redis store property

? redis {

? ? host = "127.0.0.1"

? ? port = "6379"

? ? password = ""

? ? database = "0"

? ? minConn = 1

? ? maxConn = 10

? ? maxTotal = 100

? ? queryLimit = 100

? }

}

## metrics configuration, only used in server side

metrics {

? enabled = false

? registryType = "compact"

? # multi exporters use comma divided

? exporterList = "prometheus"

? exporterPrometheusPort = 9898

}

? 我的file.conf.example文件配置

? ?需要注意的是 service里面的配置? vgroupMapping.my_test_tx_group = "default";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?default.grouplist = "127.0.0.1:8091"

transport {

? # tcp udt unix-domain-socket

? type = "TCP"

? #NIO NATIVE

? server = "NIO"

? #enable heartbeat

? heartbeat = true

? # the client batch send request enable

? enableClientBatchSendRequest = true

? #thread factory for netty

? threadFactory {

? ? bossThreadPrefix = "NettyBoss"

? ? workerThreadPrefix = "NettyServerNIOWorker"

? ? serverExecutorThread-prefix = "NettyServerBizHandler"

? ? shareBossWorker = false

? ? clientSelectorThreadPrefix = "NettyClientSelector"

? ? clientSelectorThreadSize = 1

? ? clientWorkerThreadPrefix = "NettyClientWorkerThread"

? ? # netty boss thread size,will not be used for UDT

? ? bossThreadSize = 1

? ? #auto default pin or 8

? ? workerThreadSize = "default"

? }

? shutdown {

? ? # when destroy server, wait seconds

? ? wait = 3

? }

? serialization = "seata"

? compressor = "none"

}

service {

? #transaction service group mapping

? vgroupMapping.my_test_tx_group = "default"

? #only support when registry.type=file, please don't set multiple addresses

? default.grouplist = "127.0.0.1:8091"

? #degrade, current not support

? enableDegrade = false

? #disable seata

? disableGlobalTransaction = false

}

client {

? rm {

? ? asyncCommitBufferLimit = 10000

? ? lock {

? ? ? retryInterval = 10

? ? ? retryTimes = 30

? ? ? retryPolicyBranchRollbackOnConflict = true

? ? }

? ? reportRetryCount = 5

? ? tableMetaCheckEnable = false

? ? reportSuccessEnable = false

? }

? tm {

? ? commitRetryCount = 5

? ? rollbackRetryCount = 5

? }

? undo {

? ? dataValidation = true

? ? logSerialization = "jackson"

? ? logTable = "undo_log"

? }

? log {

? ? exceptionRate = 100

? }

}


?我的registry.conf文件配置

這個注冊的話,采用的是eureka的配置;這里會把seata服務注冊到eureka;

registry {

? # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa

? type = "eureka"

? loadBalance = "RandomLoadBalance"

? loadBalanceVirtualNodes = 10

? nacos {

? ? application = "seata-server"

? ? serverAddr = "127.0.0.1:8848"

? ? group = "SEATA_GROUP"

? ? namespace = ""

? ? cluster = "default"

? ? username = ""

? ? password = ""

? }

? eureka {

? ? serviceUrl = "http://localhost:8761/eureka"

? ? application = "default"

? ? weight = "1"

? }

? redis {

? ? serverAddr = "localhost:6379"

? ? db = 0

? ? password = ""

? ? cluster = "default"

? ? timeout = 0

? }

? zk {

? ? cluster = "default"

? ? serverAddr = "127.0.0.1:2181"

? ? sessionTimeout = 6000

? ? connectTimeout = 2000

? ? username = ""

? ? password = ""

? }

? consul {

? ? cluster = "default"

? ? serverAddr = "127.0.0.1:8500"

? }

? etcd3 {

? ? cluster = "default"

? ? serverAddr = "http://localhost:2379"

? }

? sofa {

? ? serverAddr = "127.0.0.1:9603"

? ? application = "default"

? ? region = "DEFAULT_ZONE"

? ? datacenter = "DefaultDataCenter"

? ? cluster = "default"

? ? group = "SEATA_GROUP"

? ? addressWaitTime = "3000"

? }

? file {

? ? name = "file.conf"

? }

}

config {

? # file、nacos 、apollo、zk、consul、etcd3

? type = "file"

? nacos {

? ? serverAddr = "127.0.0.1:8848"

? ? namespace = ""

? ? group = "SEATA_GROUP"

? ? username = ""

? ? password = ""

? }

? consul {

? ? serverAddr = "127.0.0.1:8500"

? }

? apollo {

? ? appId = "seata-server"

? ? apolloMeta = "http://192.168.1.204:8801"

? ? namespace = "application"

? ? apolloAccesskeySecret = ""

? }

? zk {

? ? serverAddr = "127.0.0.1:2181"

? ? sessionTimeout = 6000

? ? connectTimeout = 2000

? ? username = ""

? ? password = ""

? }

? etcd3 {

? ? serverAddr = "http://localhost:2379"

? }

? file {

? ? name = "file.conf"

? }

}

二.2.接下來創建seata所需要的的數據庫和表;

根據 file.conf文件里面的db連接的數據庫名,當然自己可以隨便改名;

我們需要創建三個表,這個表是給seata-server用的;

需要以下三張表;建表sql如下;

CREATE TABLE `branch_table` (

? `branch_id` bigint(20) NOT NULL,

? `xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

? `transaction_id` bigint(20) NULL DEFAULT NULL,

? `resource_group_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `branch_type` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `status` tinyint(4) NULL DEFAULT NULL,

? `client_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `gmt_create` datetime(6) NULL DEFAULT NULL,

? `gmt_modified` datetime(6) NULL DEFAULT NULL,

? PRIMARY KEY (`branch_id`) USING BTREE,

? INDEX `idx_xid`(`xid`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------

-- Table structure for global_table

-- ----------------------------

DROP TABLE IF EXISTS `global_table`;

CREATE TABLE `global_table`? (

? `xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

? `transaction_id` bigint(20) NULL DEFAULT NULL,

? `status` tinyint(4) NOT NULL,

? `application_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `transaction_service_group` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `transaction_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `timeout` int(11) NULL DEFAULT NULL,

? `begin_time` bigint(20) NULL DEFAULT NULL,

? `application_data` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `gmt_create` datetime(0) NULL DEFAULT NULL,

? `gmt_modified` datetime(0) NULL DEFAULT NULL,

? PRIMARY KEY (`xid`) USING BTREE,

? INDEX `idx_gmt_modified_status`(`gmt_modified`, `status`) USING BTREE,

? INDEX `idx_transaction_id`(`transaction_id`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------

-- Table structure for lock_table

-- ----------------------------

DROP TABLE IF EXISTS `lock_table`;

CREATE TABLE `lock_table`? (

? `row_key` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

? `xid` varchar(96) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `transaction_id` bigint(20) NULL DEFAULT NULL,

? `branch_id` bigint(20) NOT NULL,

? `resource_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `table_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `pk` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `gmt_create` datetime(0) NULL DEFAULT NULL,

? `gmt_modified` datetime(0) NULL DEFAULT NULL,

? PRIMARY KEY (`row_key`) USING BTREE,

? INDEX `idx_branch_id`(`branch_id`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;


二.2此時去github上down我們的項目(地址:https://github.com/chengshugithub/springcloud-eureka-feign-seata);

? ?@1然后每個服務下面都有創建自己表的sql語句;然后根據配置文件去創建每個服務的庫;

? ?@2 我們服務的事物提交主要是通過seata服務去提交這個全局的事物,每一個服務的數據庫都需要去創建一張這個表,sql如下;

CREATE TABLE `undo_log` (

? `id` bigint(20) NOT NULL AUTO_INCREMENT,

? `branch_id` bigint(20) NOT NULL,

? `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

? `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

? `rollback_info` longblob NOT NULL,

? `log_status` int(11) NOT NULL,

? `log_created` datetime(0) NOT NULL,

? `log_modified` datetime(0) NOT NULL,

? `ext` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? PRIMARY KEY (`id`) USING BTREE,

? UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

?@3然后每個服務下面都需要去增加file.conf和regist.conf文件,這個regist.conf文件其實就是seata-server下的file.conf.example的文件;具體的在項目里面看;


@4 總結一下:如果想把自己的項目整合到seata-server管理。

? ? ? ?@4.1 引入setata依賴:(因為依賴放在這格式會亂,所以就不放了)

? ? ? @4.2? resources下配置file.conf文件和 registry.conf文件;

? ? ? @4.3 數據庫里面增加一個undo_log的表;

? ? ? @4.4 修改配置文件,如下:


? ? ?@4.5 數據源交給setata代理處理;(代碼上有)

? ? @4.6? 然后代碼塊使用@GlobalTransactional注解

三.此時我們再進行運行程序;

? ?1.啟動 eureka-server

? ?2.啟動 seatea-serer

? ?3.陸續啟動自己demo的三個服務;

? 4.http://localhost:8180/order/create?userId=1&productId=1&count=10&money=100;

( 邏輯的話自己看就好了,基本上是訂單調用庫存,庫存減少,賬戶減少)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容