seate-server有三种方式存储事务信息:file、db、redis;在file模式下,它将信息存储在文件/seata-server/sessionStore/root.data里,我们可以去机器上查看下文件的具体内容
% docker exec -it 016d4f7a3820 bin/sh## cat ./sessionStore/root.data_A�k,��`apimy_test_tx_grouptestBiz!172.23.0.2:8091:18450265429737473��|�q�A�k,�A�k,�"jdbc:mysql://127.0.0.1:3306/fescarstock_tbl:1api:172.23.0.1:57232!172.23.0.2:8091:18450265429737473�A�k,�A�k,�"jdbc:mysql://127.0.0.1:3306/fescar
对于一些对要求比较高的场景,需要把这些信息存储到mysql里,下面我们配置下mysql模式,然后启动。首先是tc端,最高版本有些bug起不来,我们回退到1.5.2版本
version: "3.1"services:mysql:image: mysql:5.7container_name: mysqlenvironment:- MYSQL_ROOT_PASSWORD=123456command: --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`中# 如有问题,请阅读上面的[注意事项]以及[使用自定义配置文件]- /Users/xiazemin/seata/seata-server/resources:/seata-server/resources- /Users/xiazemin/seata/seata-server/logs:/root/logs/seata/depends_on:- mysqlextra_hosts:- host.docker.internal:host-gateway
启动mysql,进入并创建对应的表
mysql> create database seata_server;Query OK, 1 row affected (0.01 sec)mysql> use seata_server;Database changedmysql>drop table if exists `global_table`;create table `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_gmt_modified_status` (`gmt_modified`, `status`),key `idx_transaction_id` (`transaction_id`));-- the table to store BranchSession datadrop table if exists `branch_table`;create table `branch_table` (`branch_id` bigint not null,`xid` varchar(128) not null,`transaction_id` bigint ,`resource_group_id` varchar(32),`resource_id` varchar(256) ,`lock_key` varchar(128) ,`branch_type` varchar(8) ,`status` tinyint,`client_id` varchar(64),`application_data` varchar(2000),`gmt_create` datetime,`gmt_modified` datetime,primary key (`branch_id`),key `idx_xid` (`xid`));-- the table to store lock datadrop table if exists `lock_table`;create table `lock_table` (`row_key` varchar(128) not null,`xid` varchar(96),`transaction_id` long ,`branch_id` long,`resource_id` varchar(256) ,`table_name` varchar(32) ,`pk` varchar(36) ,`gmt_create` datetime ,`gmt_modified` datetime,primary key(`row_key`));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;
启动服务
% docker compose -f seata/exp2/docker-compose.yaml up[+] Running 2/2⠿ Container mysql Created 0.0s⠿ Container exp2-seata-server-1 Created 0.2sAttaching to exp2-seata-server-1, mysqlmysql | 2023-09-17 01:14:28+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.40-1.el7 started.mysql | 2023-09-17 01:14:29+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'mysql | 2023-09-17 01:14:29+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.40-1.el7 started.mysql | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'mysql | 2023-09-17T01:14:30.365334Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).mysql | 2023-09-17T01:14:30.372460Z 0 [Note] mysqld (mysqld 5.7.40) starting as process 1 ...mysql | 2023-09-17T01:14:30.378981Z 0 [Note] InnoDB: PUNCH HOLE support availablemysql | 2023-09-17T01:14:30.379058Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtinsmysql | 2023-09-17T01:14:30.379079Z 0 [Note] InnoDB: Uses event mutexesmysql | 2023-09-17T01:14:30.379097Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barriermysql | 2023-09-17T01:14:30.379116Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.12mysql | 2023-09-17T01:14:30.379128Z 0 [Note] InnoDB: Using Linux native AIOmysql | 2023-09-17T01:14:30.379684Z 0 [Note] InnoDB: Number of pools: 1mysql | 2023-09-17T01:14:30.380177Z 0 [Note] InnoDB: Using CPU crc32 instructionsmysql | 2023-09-17T01:14:30.394469Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128Mmysql | 2023-09-17T01:14:30.444327Z 0 [Note] InnoDB: Completed initialization of buffer poolmysql | 2023-09-17T01:14:30.459450Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().mysql | 2023-09-17T01:14:30.476447Z 0 [Note] InnoDB: Highest supported file format is Barracuda.mysql | 2023-09-17T01:14:30.734450Z 0 [Note] InnoDB: Creating shared tablespace for temporary tablesmysql | 2023-09-17T01:14:30.734581Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...mysql | 2023-09-17T01:14:30.880452Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.mysql | 2023-09-17T01:14:30.885097Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.mysql | 2023-09-17T01:14:30.885179Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.mysql | 2023-09-17T01:14:30.896166Z 0 [Note] InnoDB: Waiting for purge to startmysql | 2023-09-17T01:14:30.948551Z 0 [Note] InnoDB: 5.7.40 started; log sequence number 12595436mysql | 2023-09-17T01:14:30.949184Z 0 [Note] Plugin 'FEDERATED' is disabled.mysql | 2023-09-17T01:14:30.963905Z 0 [Note] InnoDB: Loading buffer pool(s) from var/lib/mysql/ib_buffer_poolmysql | 2023-09-17T01:14:30.980757Z 0 [Note] InnoDB: Buffer pool(s) load completed at 230917 1:14:30mysql | 2023-09-17T01:14:31.014909Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.mysql | 2023-09-17T01:14:31.014981Z 0 [Note] Skipping generation of SSL certificates as certificate files are present in data directory.mysql | 2023-09-17T01:14:31.015090Z 0 [Warning] A deprecated TLS version TLSv1 is enabled. Please use TLSv1.2 or higher.mysql | 2023-09-17T01:14:31.015102Z 0 [Warning] A deprecated TLS version TLSv1.1 is enabled. Please use TLSv1.2 or higher.mysql | 2023-09-17T01:14:31.018564Z 0 [Warning] CA certificate ca.pem is self signed.mysql | 2023-09-17T01:14:31.018668Z 0 [Note] Skipping generation of RSA key pair as key files are present in data directory.mysql | 2023-09-17T01:14:31.028372Z 0 [Note] Server hostname (bind-address): '*'; port: 3306mysql | 2023-09-17T01:14:31.029194Z 0 [Note] IPv6 is available.mysql | 2023-09-17T01:14:31.029362Z 0 [Note] - '::' resolves to '::';mysql | 2023-09-17T01:14:31.029557Z 0 [Note] Server socket created on IP: '::'.mysql | 2023-09-17T01:14:31.092331Z 0 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.mysql | 2023-09-17T01:14:31.135045Z 0 [Note] Event Scheduler: Loaded 0 eventsmysql | 2023-09-17T01:14:31.136386Z 0 [Note] mysqld: ready for connections.mysql | Version: '5.7.40' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)exp2-seata-server-1 | ███████╗███████╗ █████╗ ████████╗ █████╗exp2-seata-server-1 | ██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔══██╗exp2-seata-server-1 | ███████╗█████╗ ███████║ ██║ ███████║exp2-seata-server-1 | ╚════██║██╔══╝ ██╔══██║ ██║ ██╔══██║exp2-seata-server-1 | ███████║███████╗██║ ██║ ██║ ██║ ██║exp2-seata-server-1 | ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝exp2-seata-server-1 |exp2-seata-server-1 |exp2-seata-server-1 | 01:14:47.513 INFO --- [ main] io.seata.server.ServerApplication : Starting ServerApplication using Java 1.8.0_212 on 1ce74f1a6ddb with PID 1 (/seata-server/classes started by root in seata-server)exp2-seata-server-1 | 01:14:47.574 INFO --- [ main] io.seata.server.ServerApplication : No active profile set, falling back to default profiles: defaultexp2-seata-server-1 | 01:15:00.397 INFO --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 7091 (http)exp2-seata-server-1 | 01:15:00.487 INFO --- [ main] o.a.coyote.http11.Http11NioProtocol : Initializing ProtocolHandler ["http-nio-7091"]exp2-seata-server-1 | 01:15:00.493 INFO --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]exp2-seata-server-1 | 01:15:00.497 INFO --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.55]exp2-seata-server-1 | 01:15:01.083 INFO --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContextexp2-seata-server-1 | 01:15:01.086 INFO --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 12815 msexp2-seata-server-1 | 01:15:07.130 INFO --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html]exp2-seata-server-1 | 01:15:09.632 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/'] with []exp2-seata-server-1 | 01:15:09.637 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.css'] with []exp2-seata-server-1 | 01:15:09.642 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.js'] with []exp2-seata-server-1 | 01:15:09.647 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.html'] with []exp2-seata-server-1 | 01:15:09.655 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.map'] with []exp2-seata-server-1 | 01:15:09.661 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.svg'] with []exp2-seata-server-1 | 01:15:09.664 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.png'] with []exp2-seata-server-1 | 01:15:09.677 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/**/*.ico'] with []exp2-seata-server-1 | 01:15:09.682 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/console-fe/public/**'] with []exp2-seata-server-1 | 01:15:09.684 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/api/v1/auth/login'] with []exp2-seata-server-1 | 01:15:09.905 INFO --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@691541bc, org.springframework.security.web.context.SecurityContextPersistenceFilter@474749b8, org.springframework.security.web.header.HeaderWriterFilter@28a6e171, org.springframework.security.web.authentication.logout.LogoutFilter@7aea704c, io.seata.console.filter.JwtAuthenticationTokenFilter@5b733ef7, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@29013ef2, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f395ce1, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@43a4a9e5, org.springframework.security.web.session.SessionManagementFilter@1f884bd6, org.springframework.security.web.access.ExceptionTranslationFilter@77cca767, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@29962b2f]exp2-seata-server-1 | 01:15:10.162 INFO --- [ main] o.a.coyote.http11.Http11NioProtocol : Starting ProtocolHandler ["http-nio-7091"]exp2-seata-server-1 | 01:15:10.315 INFO --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 7091 (http) with context path ''exp2-seata-server-1 | 01:15:10.410 INFO --- [ main] io.seata.server.ServerApplication : Started ServerApplication in 31.949 seconds (JVM running for 38.918)exp2-seata-server-1 | 01:15:14.840 INFO --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} initedexp2-seata-server-1 | 01:15:16.443 INFO --- [ main] i.s.core.rpc.netty.NettyServerBootstrap : Server started, service listen port: 8091exp2-seata-server-1 | 01:15:16.674 INFO --- [ main] io.seata.server.ServerRunner : seata server started in 6241 millSeconds
在tc server端,比较重要的配置是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: 123456min-conn: 5max-conn: 100global-table: global_tablebranch-table: branch_tablelock-table: lock_tabledistributed-lock-table: distributed_lockquery-limit: 100max-wait: 5000# 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
在应用端有两个重要的配置文件registry.conf和file.conf:
registry.conf:该配置用于指定 TC 的注册中心和配置文件,默认都是 file; 如果使用其他的注册中心,要求 Seata-Server 也注册到该配置中心上
file.conf:该配置用于指定TC的相关属性;如果使用注册中心也可以将配置添加到配置中心
切换到db存储,我们需要在应用端改下第二个文件:src/main/resources/file.conf它会被打包到target/classes/file.conf,我们需要重点改下db具体内容如下:
transport {# tcp udt unix-domain-sockettype = "TCP"#NIO NATIVEserver = "NIO"#enable heartbeatheartbeat = true#thread factory for nettythread-factory {boss-thread-prefix = "NettyBoss"worker-thread-prefix = "NettyServerNIOWorker"server-executor-thread-prefix = "NettyServerBizHandler"share-boss-worker = falseclient-selector-thread-prefix = "NettyClientSelector"client-selector-thread-size = 1client-worker-thread-prefix = "NettyClientWorkerThread"# netty boss thread size,will not be used for UDTboss-thread-size = 1#auto default pin or 8worker-thread-size = 8}shutdown {# when destroy server, wait secondswait = 3}serialization = "seata"compressor = "none"}service {#vgroup->rgroupvgroupMapping.my_test_tx_group = "default"#only support single nodedefault.grouplist = "127.0.0.1:8091"#degrade current not supportenableDegrade = false#disabledisable = false#unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanentmax.commit.retry.timeout = "-1"max.rollback.retry.timeout = "-1"}client {async.commit.buffer.limit = 10000lock {retry.internal = 10retry.times = 30}report.retry.count = 5}## transaction log storestore {## store mode: file、dbmode = "db"## file storefile {dir = "sessionStore"# branch session size , if exceeded first try compress lockkey, still exceeded throws exceptionsmax-branch-session-size = 16384# globe session size , if exceeded throws exceptionsmax-global-session-size = 512# file buffer size , if exceeded allocate new bufferfile-write-buffer-cache-size = 16384# when recover batch read sizesession.reload.read_size = 100# async, syncflush-disk-mode = async}## database storedb {## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.datasource = "dbcp"## mysql/oracle/h2/oceanbase etc.db-type = "mysql"url = "jdbc:mysql://127.0.0.1:3306/seata_server"user = "mysql"password = "123456"min-conn = 1max-conn = 3global.table = "global_table"branch.table = "branch_table"lock-table = "lock_table"query-limit = 100}}lock {## the lock store mode: local、remotemode = "remote"local {## store locks in user's database}remote {## store locks in the seata's server}}recovery {committing-retry-delay = 30asyn-committing-retry-delay = 30rollbacking-retry-delay = 30timeout-retry-delay = 30}transaction {undo.data.validation = trueundo.log.serialization = "jackson"}## metrics settingsmetrics {enabled = falseregistry-type = "compact"# multi exporters use comma dividedexporter-list = "prometheus"exporter-prometheus-port = 9898}
然后我们启动api的例子,看下
% /usr/bin/env /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -cp /var/folders/2n/42n_1dfd6kjd6s3k7bt4cb3h0000gn/T/cp_5dao53bnilynlwjde6nptexag.jar io.seata.samples.api.BussinessC00321SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: Defaulting to no-operation (NOP) logger implementationSLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".SLF4J: Defaulting to no-operation MDCAdapter implementation.SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.begin trx, xid is 172.27.0.3:8091:2745773696714344596199true
执行成功了。为了看到,db存了啥,可以在事务开始的地方打上断点
tx.begin(6000, "testBiz");System.out.println("begin trx, xid is " + tx.getXid());
调试下,然后看下数据库的内容
mysql> 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.27.0.3:8091:27457736967143435 | 27457736967143435 | 6 | api | my_test_tx_group | testBiz | 6000 | 1694916397824 | NULL | 2023-09-17 10:06:37 | 2023-09-17 10:06:44 |+-----------------------------------+-------------------+--------+----------------+---------------------------+------------------+---------+---------------+------------------+---------------------+---------------------+1 row in set (0.00 sec)
注意下,我们启动事务的时候传入了超时时间,达到超时时间后,会删除这条记录,也就是说,这个全局事务id只是在事务执行期间存在,如果事务回滚或者提交,这条记录会随之消失。
文章转载自golang算法架构leetcode技术php,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




