https://github.com/seata/seata-go是https://github.com/seata/seata的golang客户端,目前支持at和tcc两种分布式事务的实现。虽然官方的文档给的例子描述了如何处理分布式事务,但是如何部署和使用语焉不详。下面介绍下两种部署方式file、db
file模式是默认的模式性能最好,因为存在本地文件中,首先部署seata-server:
## Licensed to the Apache Software Foundation (ASF) under one or more# contributor license agreements. See the NOTICE file distributed with# this work for additional information regarding copyright ownership.# The ASF licenses this file to You under the Apache License, Version 2.0# (the "License"); you may not use this file except in compliance with# the License. You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#version: '3'services:seata-server:image: seataio/seata-server:1.5.2ports:- "8091:8091"- "7091:7091"environment:- SEATA_PORT=8091- STORE_MODE=filezookeeper:image: zookeeperports:- "2181:2181"restart: on-failuremysql:image: mysql:5.7container_name: mysqlenvironment:- MYSQL_ROOT_PASSWORD=12345678command: --default-authentication-plugin=mysql_native_password --default-time-zone='+08:00'volumes:- ./mysql:/docker-entrypoint-initdb.d- ./mysql/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnfports:- "3306:3306"
docker compose -f seata-go/sample/dockercompose/docker-compose.yml up
然后运行我们的example
go run github.com/seata/seata-go/sample/at/basic
发现我们成功运行了
127.0.0.1:3306)/seata_client, applicationData2022-12-10 21:23:49.510 INFO getty/getty_remoting.go:79 send async message: {message.RpcMessage{ID:3, Type:0x1, Codec:0x1, Compressor:0x0, HeadMap:map[string]string(nil), Body:message.BranchCommitResponse{AbstractBranchEndResponse:message.AbstractBranchEndResponse{AbstractTransactionResponse:message.AbstractTransactionResponse{AbstractResultMessage:message.AbstractResultMessage{ResultCode:0x1, Msg:""}, TransactionErrorCode:0}, Xid:"172.20.0.3:8091:27358463220736003", BranchId:27358463220736004, BranchStatus:5}}}}2022-12-10 21:23:49.510 INFO client/rm_branch_commit_processor.go:90 send branch commit success: xid 172.20.0.3:8091:27358463220736003, branchID 27358463220736004, resourceID root:12345678@tcp(127.0.0.1:3306)/seata_client, applicationData []
db模式相对复杂一些,我们需要修改配置
version: "3.1"services:mysql:image: mysql:5.7container_name: mysqlenvironment:- MYSQL_ROOT_PASSWORD=12345678command: --default-authentication-plugin=mysql_native_password --default-time-zone='+08:00'volumes:- ./mysql:/docker-entrypoint-initdb.d- ./mysql/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnfports:- "3306:3306"extra_hosts:- host.docker.internal:host-gatewayseata-server:image: seataio/seata-server:1.5.2ports:- "7091:7091"- "8091:8091"environment:- STORE_MODE=db# 以SEATA_IP作为host注册seata server# - SEATA_IP=host.docker.internal# - SEATA_PORT=8091volumes:# - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" #设置系统时区# - "/usr/share/zoneinfo/Asia/Shanghai:/etc/timezone" #设置时区# 假设我们通过docker cp命令把资源文件拷贝到相对路径`./seata-server/resources`中# 如有问题,请阅读上面的[注意事项]以及[使用自定义配置文件]- "./seata-server/resources/resources:/seata-server/resources"depends_on:- mysqlextra_hosts:- host.docker.internal:host-gateway
其中,我们可以把配置文件拷贝出来修改下
docker cp 6df7f484515e:/seata-server/resources ./seata-server/resources
修改后的application.yml如下:
server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 127.0.0.1:4560kafka-appender:bootstrap-servers: 127.0.0.1:9092topic: logback_to_logstashconsole:user:username: seatapassword: seataseata:config:# support: nacos, consul, apollo, zk, etcd3type: fileregistry:# support: nacos, eureka, redis, zk, consul, etcd3, sofatype: filestore:# support: file 、 db 、 redismode: dbdb:datasource: druiddbType: mysql# 需要根据mysql的版本调整driverClassName# mysql8及以上版本对应的driver:com.mysql.cj.jdbc.Driver# mysql8以下版本的driver:com.mysql.jdbc.DriverdriverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://host.docker.internal:3306/seata_server?useUnicode=true&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=falseuser: rootpassword: 12345678# server:# service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
其中三点改动需要关注
1,- STORE_MODE=file改成了- STORE_MODE=db
2,地址需要改成host.docker.internal,原因在前面的系列文章中介绍过
3,dsn的数据库名需要改成seata_server
否则会报错
java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
启动
docker compose -f docker-compose-db.yaml up
最后链接上mysql,创建我们依赖的库和表
-- -------------------------------- The script used when storeMode is 'db' --------------------------------create database `seata_server`;use `seata_server`;-- the table to store GlobalSession dataCREATE 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 dataCREATE 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 dataCREATE 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` (`xid`)) 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);create database seata_client;use seata_client;CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,`ext` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `storage_tbl`;CREATE TABLE `storage_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`commodity_code` varchar(255) DEFAULT NULL,`count` int(11) DEFAULT 0,PRIMARY KEY (`id`),UNIQUE KEY (`commodity_code`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `order_tbl`;CREATE TABLE `order_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) DEFAULT NULL,`commodity_code` varchar(255) DEFAULT NULL,`count` int(11) DEFAULT 0,`money` int(11) DEFAULT 0,`descs` varchar(255) DEFAULT "",PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `account_tbl`;CREATE TABLE `account_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) DEFAULT NULL,`money` int(11) DEFAULT 0,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql -uroot -p12345678 -h127.0.0.1 -e 'source mysql.sql'
需要注意的是,官方默认的数据库创建文件里少了个字段,导致跑不起来,需要加个字段
CREATE TABLE `order_tbl``descs` varchar(255) DEFAULT "",
启动我们的seata-go
% go run github.com/seata/seata-go/sample/at/basic2022-12-10 22:13:05.384 INFO client/rm_branch_commit_processor.go:90 send branch commit success: xid 172.19.0.3:8091:27358476928553095, branchID 27358476928553097, resourceID root:12345678@tcp(127.0.0.1:3306)/seata_client, applicationData []
发现已经成功了。
调试追踪过程中我们发现,会创建这种全局锁,事务完成后提交。
select * from global_table;+-----------------------------------+-------------------+--------+----------------+---------------------------+-----------------------+---------+---------------+------------------+---------------------+---------------------+| xid | transaction_id | status | application_id | transaction_service_group | transaction_name | timeout | begin_time | application_data | gmt_create | gmt_modified |+-----------------------------------+-------------------+--------+----------------+---------------------------+-----------------------+---------+---------------+------------------+---------------------+---------------------+| 172.19.0.3:8091:27358476928553113 | 27358476928553113 | 1 | seata-go | 127.0.0.1:8091 | ATSampleLocalGlobalTx | 30000 | 1670682517809 | NULL | 2022-12-10 22:28:37 | 2022-12-10 22:28:37 |+-----------------------------------+-------------------+--------+----------------+---------------------------+-----------------------+---------+---------------+------------------+---------------------+---------------------+1 row in set (0.00 sec)


文章转载自golang算法架构leetcode技术php,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




