seata(2):db mode

2023-09-20 08:31:26 浏览数 (2)

seate-server有三种方式存储事务信息:file、db、redis;在file模式下,它将信息存储在文件/seata-server/sessionStore/root.data里,我们可以去机器上查看下文件的具体内容

代码语言:javascript复制
 % 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/fescar
                                                                                                                       stock_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版本

代码语言:javascript复制
version: "3.1"
services:
  mysql:
    image: mysql:5.7
    container_name: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=123456
    command: --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.cnf
    ports:
      - "3306:3306"
    extra_hosts:
     - host.docker.internal:host-gateway

  seata-server:
    image: seataio/seata-server:1.5.2
    ports:
      - "7091:7091"
      - "8091:8091"
    environment:
      - STORE_MODE=db
      # 以SEATA_IP作为host注册seata server
      # - SEATA_IP=host.docker.internal
      # - SEATA_PORT=8091
    volumes:
      # - "/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:
      - mysql
    extra_hosts:
     - host.docker.internal:host-gateway

启动mysql,进入并创建对应的表

代码语言:javascript复制
mysql> create database seata_server;
Query OK, 1 row affected (0.01 sec)

mysql> use seata_server;
Database changed
mysql>



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 data
drop 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 data
drop 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;

启动服务

代码语言:javascript复制
% docker compose -f seata/exp2/docker-compose.yaml up
[ ] Running 2/2
 ⠿ Container mysql                Created                                                 0.0s
 ⠿ Container exp2-seata-server-1  Created                                                 0.2s
Attaching to exp2-seata-server-1, mysql
mysql                | 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 available
mysql                | 2023-09-17T01:14:30.379058Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
mysql                | 2023-09-17T01:14:30.379079Z 0 [Note] InnoDB: Uses event mutexes
mysql                | 2023-09-17T01:14:30.379097Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
mysql                | 2023-09-17T01:14:30.379116Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.12
mysql                | 2023-09-17T01:14:30.379128Z 0 [Note] InnoDB: Using Linux native AIO
mysql                | 2023-09-17T01:14:30.379684Z 0 [Note] InnoDB: Number of pools: 1
mysql                | 2023-09-17T01:14:30.380177Z 0 [Note] InnoDB: Using CPU crc32 instructions
mysql                | 2023-09-17T01:14:30.394469Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
mysql                | 2023-09-17T01:14:30.444327Z 0 [Note] InnoDB: Completed initialization of buffer pool
mysql                | 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 tables
mysql                | 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 start
mysql                | 2023-09-17T01:14:30.948551Z 0 [Note] InnoDB: 5.7.40 started; log sequence number 12595436
mysql                | 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_pool
mysql                | 2023-09-17T01:14:30.980757Z 0 [Note] InnoDB: Buffer pool(s) load completed at 230917  1:14:30
mysql                | 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: 3306
mysql                | 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 events
mysql                | 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: default
exp2-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 WebApplicationContext
exp2-seata-server-1  | 01:15:01.086  INFO --- [                     main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 12815 ms
exp2-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} inited
exp2-seata-server-1  | 01:15:16.443  INFO --- [                     main] i.s.core.rpc.netty.NettyServerBootstrap  : Server started, service listen port: 8091
exp2-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如果不正确是起不来的,内容如下

代码语言:javascript复制
server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${user.home}/logs/seata
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash

console:
  user:
    username: seata
    password: seata

seata:
  config:
    # support: nacos, consul, apollo, zk, etcd3
    type: file
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: file
  store:
    # support: file 、 db 、 redis
    mode: db
    db:
      datasource: druid
      dbType: mysql
      # 需要根据mysql的版本调整driverClassName
      # mysql8及以上版本对应的driver:com.mysql.cj.jdbc.Driver
      # mysql8以下版本的driver:com.mysql.jdbc.Driver
      driverClassName: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://host.docker.internal:3306/seata_server?useUnicode=true&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
      user: root
      password: 123456
      min-conn: 5
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      query-limit: 100
      max-wait: 5000
      
  #  server:
  #    service-port: 8091 #If not configured, the default is '${server.port}   1000'
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      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具体内容如下:

代码语言:javascript复制
transport {
  # tcp udt unix-domain-socket
  type = "TCP"
  #NIO NATIVE
  server = "NIO"
  #enable heartbeat
  heartbeat = true
  #thread factory for netty
  thread-factory {
    boss-thread-prefix = "NettyBoss"
    worker-thread-prefix = "NettyServerNIOWorker"
    server-executor-thread-prefix = "NettyServerBizHandler"
    share-boss-worker = false
    client-selector-thread-prefix = "NettyClientSelector"
    client-selector-thread-size = 1
    client-worker-thread-prefix = "NettyClientWorkerThread"
    # netty boss thread size,will not be used for UDT
    boss-thread-size = 1
    #auto default pin or 8
    worker-thread-size = 8
  }
  shutdown {
    # when destroy server, wait seconds
    wait = 3
  }
  serialization = "seata"
  compressor = "none"
}
service {
  #vgroup->rgroup
  vgroupMapping.my_test_tx_group = "default"
  #only support single node
  default.grouplist = "127.0.0.1:8091"
  #degrade current not support
  enableDegrade = false
  #disable
  disable = false
  #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
  max.commit.retry.timeout = "-1"
  max.rollback.retry.timeout = "-1"
}

client {
  async.commit.buffer.limit = 10000
  lock {
    retry.internal = 10
    retry.times = 30
  }
  report.retry.count = 5
}

## transaction log store
store {
  ## store mode: file、db
  mode = "db"

  ## file store
  file {
    dir = "sessionStore"

    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    max-branch-session-size = 16384
    # globe session size , if exceeded throws exceptions
    max-global-session-size = 512
    # file buffer size , if exceeded allocate new buffer
    file-write-buffer-cache-size = 16384
    # when recover batch read size
    session.reload.read_size = 100
    # async, sync
    flush-disk-mode = async
  }

  ## database store
  db {
    ## 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 = 1
    max-conn = 3
    global.table = "global_table"
    branch.table = "branch_table"
    lock-table = "lock_table"
    query-limit = 100
  }
}
lock {
  ## the lock store mode: local、remote
  mode = "remote"

  local {
    ## store locks in user's database
  }

  remote {
    ## store locks in the seata's server
  }
}
recovery {
  committing-retry-delay = 30
  asyn-committing-retry-delay = 30
  rollbacking-retry-delay = 30
  timeout-retry-delay = 30
}

transaction {
  undo.data.validation = true
  undo.log.serialization = "jackson"
}

## metrics settings
metrics {
  enabled = false
  registry-type = "compact"
  # multi exporters use comma divided
  exporter-list = "prometheus"
  exporter-prometheus-port = 9898
}

然后我们启动api的例子,看下

代码语言:javascript复制
%  /usr/bin/env /Library/Internet Plug-Ins/Ja
vaAppletPlugin.plugin/Contents/Home/bin/java -cp /var/folders/2n/42n_1dfd6kjd6s3k
7bt4cb3h0000gn/T/cp_5dao53bnilynlwjde6nptexag.jar io.seata.samples.api.Bussiness 

C00321
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: 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:27457736967143445
96
199
true

执行成功了。为了看到,db存了啥,可以在事务开始的地方打上断点

代码语言:javascript复制
  tx.begin(6000, "testBiz");
  System.out.println("begin trx, xid is "   tx.getXid());

调试下,然后看下数据库的内容

代码语言:javascript复制
 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只是在事务执行期间存在,如果事务回滚或者提交,这条记录会随之消失。

0 人点赞