Docker搭建Seata环境

2023-11-01

Docker搭建Seata环境

  1. 添加seata需要的数据库表

直接点击
mysql数据库
oracle数据库
postgresql数据库

  1. 为业务数据库也添加一个undo_log表

Seata的AT模式下之所以在第一阶段直接提交事务,依赖的是需要在每个RM创建一张undo_log表,记录业务执行前后的数据快照。

如果二阶段需要回滚,直接根据undo_log表回滚,如果执行成功,则在第二阶段删除对应的快照数据。

直接点击
mysql数据库
oracle数据库
postgresql数据库

  1. 拉取seata镜像
docker pull seataio/seata-server:1.4.0
  1. 临时启动seata容器,复制出来registry.conf配置文件
docker run -d --name seata-server -p 8091:8091 seataio/seata- server:1.4.0

docker cp seata-server:/seata-server/resources/registry.conf /seata/config
  1. 删除刚才的临时容器
docker rm -f seata-server
  1. 修改registry.conf配置文件,服务注册和配置读取设置成nacos
registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  nacos {
    application = "seata-server"
    serverAddr = "47.96.234.28:8848"
    group = "DEFAULT_GROUP"
    namespace = "mom_dev"
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"

  nacos {
    serverAddr = "47.96.234.28:8848"
    group = "DEFAULT_GROUP"
    namespace = "seata_config"
    username = "nacos"
    password = "nacos"
  }
  file {
    name = "file.conf"
  }
}

  1. 推送seata配置到nacos

!!!如果现有nacos已经配置好了seata,那么就不需要再执行此步骤!

由于新版本的seata不带config.txt 和推送脚本文件 nacos-config. sh,所以需要直接在GitHub上下载。

下载地址

文件目录位置:

├── config.txt
└── nacos
    └── nacos-config.sh

如果进不去GitHub,可以直接点 config.txtnacos-config.sh。自己创建文件复制进去即可。

修改config.txt文件中的事务组和MySQL连接信息,修改信息如下:

client.undo.logSerialization=kryo

service.vgroupMapping.mom_tx_group=default

store.mode=db
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://47.96.234.28:3303/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=123456

默认的日志序列化程序不可用, jackson 的新特性找不到,Seata 要求 jackson 版本2.9.9+,但是使用 jackson 2.9.9+ 版本会导致Spring Boot中使用的jackson API找不到,也就是jackson本身的向前兼容性存在问题。因此,这里将Seata的序列化方式切换到非 jackson 序列化方式,比如 kryo,配置项为client.undo.logSerialization = “kryo”。

推送到nacos

bash nacos-config.sh -h 127.0.0.1 -p 8848 -g DEFAULT_GROUP -t seata_config -u nacos -w nacos
  • p:端口
  • h:nacos地址
  • g:配置组
  • t:命名空间id
  • u:账号
  • w:密码

推送成功后会有以下配置文件

在这里插入图片描述

  1. 启动Seata

docker-compose.yml

version: "3"
services:
  seata-server:
    image: seataio/seata-server:1.4.0
    container_name: seata-server
    hostname: seata-server
    ports:
      - "8091:8091"
    environment:
      - SEATA_PORT=8091
      - SEATA_IP=47.96.234.28
      - SEATA_CONFIG_NAME=file:/seata-server/resources/registry.conf
    volumes:
      - ./config/registry.conf:/seata-server/resources/registry.conf

SEATA_IP一定要写成外网ip,不然会访问不了

然后直接启动即可。

Spring Cloud端配置

  1. 添加pom依赖
        <!--seata-->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.4.0</version>
        </dependency>

        <!--        kryo集成-->
        <dependency>
            <groupId>com.esotericsoftware.kryo</groupId>
            <artifactId>kryo</artifactId>
            <version>2.24.0</version>
        </dependency>
        <dependency>
            <groupId>de.javakaffee</groupId>
            <artifactId>kryo-serializers</artifactId>
            <version>0.45</version>
        </dependency>
        <dependency>
            <groupId>com.esotericsoftware</groupId>
            <artifactId>kryo</artifactId>
            <version>4.0.2</version>
        </dependency>

需要指定seata版本和seata-server版本一致,这里也就是1.4.0

  1. yml文件配置

bootstrap.yml,自己根据自己的nacos、seata配置。

spring:
  application:
    name: mom-tms-server

  cloud:
    nacos:
      discovery:
        username: ${NACOS_USER:nacos}
        password: ${NACOS_PWD:nacos}
        server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
        group: DEFAULT_GROUP
        namespace: ${NACOS_NAMESPACE:mom_dev}
        enabled: true
        register-enabled: true
      config:
        username: ${NACOS_USER:nacos}
        password: ${NACOS_PWD:nacos}
        server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
        group: DEFAULT_GROUP
        namespace: ${NACOS_NAMESPACE:mom_dev}
        file-extension: yml
        refresh-enabled: true

# 分布式事务配置
seata:
  tx-service-group: mom_tx_group
  enable-auto-data-source-proxy: true
  registry:
    type: nacos
    nacos:
      username: ${NACOS_USER:nacos}
      password: ${NACOS_PWD:nacos}
      server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
      namespace: ${NACOS_NAMESPACE:mom_dev}
      group: DEFAULT_GROUP
  config:
    type: nacos
    nacos:
      username: ${NACOS_USER:nacos}
      password: ${NACOS_PWD:nacos}
      server-addr: ${NACOS_HOST:localhost}:${NACOS_PORT:8848}
      namespace: ${NACOS_NAMESPACE_SEATA:seata_config}
      group: DEFAULT_GROUP
  service:
    vgroup-mapping:
      mom_tx_group: default
  • tx-service-group: mom_tx_group 配置事务群组,其中群组名称 mom_tx_group 需和服务端的配置 service.vgroupMapping.mom_tx_group=default 一致
  • enable-auto-data-source-proxy: true 自动为Seata开启了代理数据源,实现集成对undo_log表操作
  • namespace: mom_dev 和seata-server一致
  • group: DEFAULT_GROUP 和seata-server一致
  1. 启动类

启动类添加@EnableAutoDataSourceProxy注解来开启seata事务配置。

  1. 为需要的业务添加@GlobalTransactional注解
@GlobalTransactional(rollbackFor = Exception.class, name = "mom_tx_group")
public boolean submit() {
    // 各种操作
    return ...;
}




下面先了解一下seata的基本工作原理,然后看一个详细的案例。

Seata术语

  • Transaction ID - XID:全局唯一事务ID

  • TC (Transaction Coordinator) - 事务协调者
    维护全局和分支事务的状态,驱动全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器
    定义全局事务的范围:开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器
    管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

seata分布式事务处理过程

在这里插入图片描述

  1. TM向TC申请开启一个全局事务,全局事务开启,并生成一个全局唯一的XID。
  2. XID在微服务在微服务调用链路的上下文中传播。
  3. RM向TC注册分之事务,将其纳入XID对应全局事物的管辖。
  4. TM向TC发起针对XID的全局提交或回滚协议。
  5. TC调度XID下管辖的全局分之事务完成提交或回滚请求。

分布式交易案例

此处引用seata官方的一个案例:用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:

  • 仓储服务:对给定的商品扣除仓储数量。
  • 订单服务:根据采购需求创建订单。
  • 帐户服务:从用户帐户中扣除余额。

架构图

在这里插入图片描述

仓储服务

public interface StorageService {

    /**
     * 扣除存储数量
     */
    void deduct(String commodityCode, int count);
}

订单服务

public interface OrderService {

    /**
     * 创建订单
     */
    Order create(String userId, String commodityCode, int orderCount);
}

账户服务

public interface AccountService {

    /**
     * 从用户账户中借出
     */
    void debit(String userId, int money);
}

主要业务逻辑

public class BusinessServiceImpl implements BusinessService {

    private StorageService storageService;

    private OrderService orderService;

    /**
     * 采购
     */
    public void purchase(String userId, String commodityCode, int orderCount) {

        // 减库存
        storageService.deduct(commodityCode, orderCount);
        
        // 创建订单、更新账户余额
        orderService.create(userId, commodityCode, orderCount);
    }
}
public class OrderServiceImpl implements OrderService {

    private OrderDAO orderDAO;

    private AccountService accountService;

    public Order create(String userId, String commodityCode, int orderCount) {

        int orderMoney = calculate(commodityCode, orderCount);

        // 更新账户yue余额
        accountService.debit(userId, orderMoney);

        Order order = new Order();
        order.userId = userId;
        order.commodityCode = commodityCode;
        order.count = orderCount;
        order.money = orderMoney;

        // 创建订单
        return orderDAO.insert(order);
    }
}
SEATA 的分布式交易解决方案

在这里插入图片描述

我们只需要使用一个 @GlobalTransactional 注解在业务方法上:

 @GlobalTransactional
    public void purchase(String userId, String commodityCode, int orderCount) {
        ......
    }

我们的MOM统一把事务加在了controller层,所以只需要在controller层的方法上添加@GlobalTransactional即可。

下面几点需要注意:

  • 如果调用服务只是用来查询,比如服务A调用服务B、服务C来查询某些数据,所有的更新操作都在服务A上,那么就不用集成seata来引用全局事务。直接采用@Transactional注解即可。
  • queryDSL不支持seata,如果有涉及到用queryDSL进行更新操作的,大家在集成seata的时候,记得要保留原来的@Transactional。如果queryDSL只是用在查询上,就不用保留原来的@Transactional。建议修改使用JPA来操作。
  • 严禁catch捕获异常之后不抛出,不允许异常捕获之后手动回滚事务。




副本文件

config.txt

transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=true
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
service.vgroupMapping.my_test_tx_group=default
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
store.mode=file
store.lock.mode=file
store.session.mode=file
store.publicKey=
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=username
store.db.password=password
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
store.redis.mode=single
store.redis.single.host=127.0.0.1
store.redis.single.port=6379
store.redis.sentinel.masterName=
store.redis.sentinel.sentinelHosts=
store.redis.maxConn=10
store.redis.minConn=1
store.redis.maxTotal=100
store.redis.database=0
store.redis.password=
store.redis.queryLimit=100
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.distributedLockExpireTime=10000
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

nacos-config.sh

#!/usr/bin/env bash
# Copyright 1999-2019 Seata.io Group.
#
# Licensed 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.

while getopts ":h:p:g:t:u:w:" opt
do
  case $opt in
  h)
    host=$OPTARG
    ;;
  p)
    port=$OPTARG
    ;;
  g)
    group=$OPTARG
    ;;
  t)
    tenant=$OPTARG
    ;;
  u)
    username=$OPTARG
    ;;
  w)
    password=$OPTARG
    ;;
  ?)
    echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] "
    exit 1
    ;;
  esac
done

urlencode() {
  for ((i=0; i < ${#1}; i++))
  do
    char="${1:$i:1}"
    case $char in
    [a-zA-Z0-9.~_-]) printf $char ;;
    *) printf '%%%02X' "'$char" ;;
    esac
  done
}

if [[ -z ${host} ]]; then
    host=localhost
fi
if [[ -z ${port} ]]; then
    port=8848
fi
if [[ -z ${group} ]]; then
    group="SEATA_GROUP"
fi
if [[ -z ${tenant} ]]; then
    tenant=""
fi
if [[ -z ${username} ]]; then
    username=""
fi
if [[ -z ${password} ]]; then
    password=""
fi

nacosAddr=$host:$port
contentType="content-type:application/json;charset=UTF-8"

echo "set nacosAddr=$nacosAddr"
echo "set group=$group"

failCount=0
tempLog=$(mktemp -u)
function addConfig() {
  curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$(urlencode $1)&group=$group&content=$(urlencode $2)&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null
  if [[ -z $(cat "${tempLog}") ]]; then
    echo " Please check the cluster status. "
    exit 1
  fi
  if [[ $(cat "${tempLog}") =~ "true" ]]; then
    echo "Set $1=$2 successfully "
  else
    echo "Set $1=$2 failure "
    (( failCount++ ))
  fi
}

count=0
for line in $(cat $(dirname "$PWD")/config.txt | sed s/[[:space:]]//g); do
  (( count++ ))
	key=${line%%=*}
    value=${line#*=}
	addConfig "${key}" "${value}"
done

echo "========================================================================="
echo " Complete initialization parameters,  total-count:$count ,  failure-count:$failCount "
echo "========================================================================="

if [[ ${failCount} -eq 0 ]]; then
	echo " Init nacos config finished, please start seata-server. "
else
	echo " init nacos config fail. "
fi

mysql数据库

/*
 Navicat Premium Data Transfer

 Source Server         : 47.96.234.28_3303
 Source Server Type    : MySQL
 Source Server Version : 50733
 Source Host           : 47.96.234.28:3303
 Source Schema         : seata

 Target Server Type    : MySQL
 Target Server Version : 50733
 File Encoding         : 65001

 Date: 04/07/2021 22:42:44
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for branch_table
-- ----------------------------
DROP TABLE IF EXISTS `branch_table`;
CREATE TABLE `branch_table` (
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(128) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `resource_group_id` varchar(32) DEFAULT NULL,
  `resource_id` varchar(256) DEFAULT NULL,
  `branch_type` varchar(8) DEFAULT NULL,
  `status` tinyint(4) DEFAULT NULL,
  `client_id` varchar(64) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime(6) DEFAULT NULL,
  `gmt_modified` datetime(6) DEFAULT NULL,
  PRIMARY KEY (`branch_id`),
  KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for global_table
-- ----------------------------
DROP TABLE IF EXISTS `global_table`;
CREATE TABLE `global_table` (
  `xid` varchar(128) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `status` tinyint(4) NOT NULL,
  `application_id` varchar(32) DEFAULT NULL,
  `transaction_service_group` varchar(32) DEFAULT NULL,
  `transaction_name` varchar(128) DEFAULT NULL,
  `timeout` int(11) DEFAULT NULL,
  `begin_time` bigint(20) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`xid`),
  KEY `idx_gmt_modified_status` (`gmt_modified`,`status`),
  KEY `idx_transaction_id` (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for lock_table
-- ----------------------------
DROP TABLE IF EXISTS `lock_table`;
CREATE TABLE `lock_table` (
  `row_key` varchar(128) NOT NULL,
  `xid` varchar(96) DEFAULT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `branch_id` bigint(20) NOT NULL,
  `resource_id` varchar(256) DEFAULT NULL,
  `table_name` varchar(32) DEFAULT NULL,
  `pk` varchar(36) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`row_key`),
  KEY `idx_branch_id` (`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'increment id',
  `branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',
  `xid` varchar(100) NOT NULL COMMENT 'global transaction id',
  `context` varchar(128) NOT NULL COMMENT 'undo_log context,such as serialization',
  `rollback_info` longblob NOT NULL COMMENT 'rollback info',
  `log_status` int(11) NOT NULL COMMENT '0:normal status,1:defense status',
  `log_created` datetime NOT NULL COMMENT 'create datetime',
  `log_modified` datetime NOT NULL COMMENT 'modify datetime',
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='AT transaction mode undo table';


SET FOREIGN_KEY_CHECKS = 1;

oracle数据库

-- Create table
create table UNDO_LOG
(
  id            NUMBER(20) not null,
  branch_id     NUMBER(20) not null,
  xid           VARCHAR2(100) not null,
  context       VARCHAR2(128) not null,
  rollback_info BLOB,
  log_status    INTEGER,
  log_created   DATE,
  log_modified  DATE
);
-- Create/Recreate indexes 
create index IDX_XRID on UNDO_LOG (BRANCH_ID, XID);
-- Create/Recreate primary, unique and foreign key constraints 
alter table UNDO_LOG
  add constraint PK_UNDO primary key (ID);
create sequence UNDO_LOG_SEQ
minvalue 1
maxvalue 9999999999999999999999999
start with 1
increment by 1
cache 20;



create table GLOBAL_TABLE (
  xid varchar2(128)  not null,
  transaction_id NUMBER(20),
  status NUMBER(10) not null,
  application_id varchar2(64),
  transaction_service_group varchar2(64),
  transaction_name varchar2(128),
  timeout NUMBER(10),
  begin_time NUMBER(20),
  application_data varchar2(2000),
  gmt_create DATE,
  gmt_modified DATE
);


create table BRANCH_TABLE (
  branch_id NUMBER(20) not null,
  xid varchar2(128) not null,
  transaction_id NUMBER(20) ,
  resource_group_id varchar2(128),
  resource_id varchar2(256) ,
  lock_key varchar2(256) ,
  branch_type varchar2(8) ,
  status NUMBER(10),
  client_id varchar2(64),
  application_data varchar2(2000),
  gmt_create DATE,
  gmt_modified DATE
);


create table LOCK_TABLE (
  row_key varchar2(128) not null,
  xid varchar2(128),
  transaction_id NUMBER(20) ,
  branch_id NUMBER(20),
  resource_id varchar2(256) ,
  table_name varchar2(64) ,
  pk varchar2(128) ,
  gmt_create DATE ,
  gmt_modified DATE
);

postgresql数据库

-- Create table
create table UNDO_LOG (
    id            NUMERIC(20) not null,
    branch_id     NUMERIC(20) not null,
    xid           VARCHAR(100) not null,
    context       VARCHAR(128) not null,
    rollback_info text,
    log_status    INTEGER,
    log_created   DATE,
    log_modified  DATE
);

-- Create/Recreate indexes
create index IDX_XRID on UNDO_LOG (BRANCH_ID, XID);

-- Create/Recreate primary, unique and foreign key constraints
alter table UNDO_LOG  add constraint PK_UNDO primary key (ID);

create sequence UNDO_LOG_SEQ minvalue 1 maxvalue 9223372036854775807 start with 1 increment by 1 cache 20;

create table GLOBAL_TABLE (
    xid varchar(128)  not null,
    transaction_id NUMERIC(20),
    status NUMERIC(10) not null,
    application_id varchar(64),
    transaction_service_group varchar(64),
    transaction_name varchar(128),
    timeout NUMERIC(10),
    begin_time NUMERIC(20),
    application_data varchar(2000),
    gmt_create DATE,  gmt_modified DATE
);

create table BRANCH_TABLE (
    branch_id NUMERIC(20) not null,
    xid varchar(128) not null,
    transaction_id NUMERIC(20) ,
    resource_group_id varchar(128),
    resource_id varchar(256) ,
    lock_key varchar(256) ,
    branch_type varchar(8) ,
    status NUMERIC(10),
    client_id varchar(64),
    application_data varchar(2000),
    gmt_create DATE,
    gmt_modified DATE
);

create table LOCK_TABLE (
    row_key varchar(128) not null,
    xid varchar(128),
    transaction_id NUMERIC(20) ,
    branch_id NUMERIC(20),
    resource_id varchar(256) ,
    table_name varchar(64) ,
    pk varchar(128) ,
    gmt_create DATE ,
    gmt_modified DATE
);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker搭建Seata环境 的相关文章

  • Linux入门级命令

    目录 1 开启终端 2 Linux命令格式 3 扩展 Linux下的命令补全 4 切换用户 5 uname命令 6 ls命令 用法一 用法二 用法三 7 pwd命令 8 cd命令 9 clear命令 10 reboot命令 11 shutd
  • MySQL表字段设置默认值

    环境 MySQL 5 1 命令行工具 问题 MySQL表字段设置默认值 解决 SQL CREATE TABLE test i a int NOT NULL DEFAULT 1 ts b timestamp NOT NULL DEFAULT
  • chrome启动参数设置

    chrome禁止本地浏览时加载本地其他文件 可以采用添加启动参数的方式来支持 添加参数为 allow file access from files 或者 disable web security Google Chrome 浏览器默认安装路
  • KDD‘21华为数值型特征做embedding,An Embedding Learning Framework for Numerical Features in CTR Prediction

    本文是针对数值型特征做embedding的方法 背景 图1 常用的数值型embedding方法可以分为以下三类 No Embedding 这类方法不做embedding 而是直接用原始的数值作为特征 或者在数值上面做一些改进 例如youtu
  • React 核心概念(3)

    React 核心概念 3 1 事件处理 React 元素的事件处理和 DOM 元素的很相似 但是有一点语法上的不同 引自 事件处理 React 事件的命名采用小驼峰式 camelCase 而不是纯小写 使用 JSX 语法时你需要传入一个函数
  • 写网关介绍比较好的文章地址

    https www jianshu com p 5bc4c0f58bf3
  • 自带内网穿透的文件同步工具Syncthing介绍

    文章目录 特征简介 下载与安装 简单介绍 后记 特征简介 Syncthing是一个文件同步工具 可以实现异地电脑间的文件同步 Syncthing自带内网穿透功能 文件同步过程将以P2P方式进行 Syncthing支持Windows MacO
  • QT中QDockWidget使用详解

    Qt系列文章目录 文章目录 Qt系列文章目录 前言 一 具体操作 1 QDockWidget控件配置函数 2 代码 1 头文件 2 实现文件 效果 遇到的问题 前言 QDockWidget提供了dock widget的概念 也称为工具面板或
  • shell脚本基础5——常用命令写作技巧

    文章目录 一 grep命令 二 sed命令 2 1 选项参数 2 2 常用命令 三 AWK命令 3 1 常用参数 3 2 常用示例 四 find与xargs 五 date命令 六 对话框 6 1 消息框 6 2 yes no对话框 6 3
  • 信息安全风险评估---矩阵法计算风险

    矩阵法计算风险 假设 有以下信息系统中资产面临威胁利用脆弱性的情况 共有两项重要财产 资产A1和资产A2 资产A1面临一个主要威胁T1 资产A2面临两个主要威胁T2 T3 威胁T1可以利用资产A1存在的两个脆弱性 脆弱性V1和V2 威胁T2
  • 小程序DOM如何转为图片并将图片分享给朋友?

    方案一 h5中转页 1 利用web端插件html2canvas将dom转成图片 h5端 入参请参考文档 http www dtmao cc ios 65361 html html2canvas refdom useCORS true sca
  • 可穿戴设备未来市场巨大

    可穿戴设备将冲击智能手机的存在 不可否认 可穿戴设备未来的市场非常之大 甚至极有可能冲击智能手机的存在 从功能角度讲 可穿戴设备有机会一步步替代智能手机 现阶段来讲 许多可穿戴设备只能算是手机的附庸产品 通讯 社交等功能以手机为基础 可穿戴
  • STM32定时器(输入捕获)

    上一章讲了输出比较的内容 输出比较就是定时器自增 同时和CCR比较 按照自己设置的比较要求 输出REF高低电平 这一章我们讲下面结构图输出比较左边部分 也就是输入捕获 首先 介绍一下输入捕获 IC input capture 输入捕获 输入
  • Vuforia SDK分析

    Vuforia Architecture 高通组件 camera 单实例 在需要摄像头的时候会返回唯一的摄像头实例 Image Converter 单实例 像素级的图像转换器 在相机的 OpenGL ES rendering 格式和 tra
  • Android中保存当前按钮的状态 按back键返回之后再次进入没有改变

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到网站 一 使用SharedPreferences类 把用户操作记录保存到里面 因为是按钮的状态 所以在点击事件里面保存用户的操作数据 获取用户
  • 哨向 Mika & Lelush 1

    Report On Sentinels Guides of Atypical Combinations 非典型性哨兵向导结合报告 1 你是我的灯塔
  • HTML5 地理定位 【来自百度应用分享平台】

    百度给的地图API接口相当完善 复制过来一下 以后备用 基本使用方法
  • Day2:跨站脚本攻击

    目标 持续输出 每日分享关于web前端常见知识 面试题 性能优化 新技术等方面的内容 篇幅不会过长 方便理解和记忆 主要面向群体 前端开发工程师 初 中 高级 应届 转行 培训等同学 Day2 今日话题 想必大家经常会在面试中或者工作生活中
  • QT从入门到实战x篇_30_绘图设备(QPixmap、QBitmap、QImage和 QPicture;QPixmap、QBitmap绘制及保存;QImage像素操作;QPicture记录和重现)

    前面QT从入门到实战x篇 27 绘图事件QPainter 绘图事件void painterEvent 声明一个画家对象 QPainter painter this 画笔QPen 画刷QBrush QT从入门到实战x篇 28 绘图事件QPai
  • 用pandas进行数据分析实战

    安装pandas模块包 载入练习数据 在pandas中 常用的载入函数是read csv 除此之外还有read excel和read table table可以读取txt 若是服务器相关的部署 则还会用到read sql 直接访问数据库 但

随机推荐

  • 机器学习基础:核密度估计(Machine Learning Fundamentals: Kernel Density Estimation)

    在概率密度估计过程中 如果我们队随机变量的分布是已知的 那么可以直接使用参数估计的方法进行估计 如最大似然估计方法 然而在实际情况中 随机变量的参数是未知的 因此需要进行非参数估计 核密度估计是非参数估计的一种方法 也就是大家经常听见的pa
  • 关于LLVM IR和Valgrind 中间语言区别

    1 LLVM和Valgrind简介 LLVM Low Level VirtualMachine 是伊利诺伊州立大学香槟分校的ChrisLattner主持开发的一个编译器框架 随着ChrisLattner去苹果公司 LLVM作为苹果公司官方支
  • pymongo使用update_many方法批量更新记录

    使用的主要函数是 coll update many 当需要对同一批数据进行更新的时候 可以用这个函数 使用时 coll update many 筛选这一批数据需要查询的内容 字典类型 set 更新的内容 字典类型 使用方法如示例代码 示例代
  • 从0搭建Hyperledger Fabric2.5环境

    Hyperledger Fabric 2 5环境搭建 一 Linux环境准备 root登录 yum y install git curl docker docker compose tree yum y install autoconf a
  • NSNumber NSValue与NSDate 详解

    我们在编码中 很多时候需要将C里面原生的数据封装成对象 这样可以用NSDictionary或者NSArray来存取访问 尤其是一些做适配的情况下 这种封装是不可避免的 Objective C提供了不少类可以帮助我们 比较常见的是NSNumb
  • [转载]Stanford华人教授李飞飞写给她学生的一封信,如何做好研究以及写好PA

    De mystifying Good Research and Good Papers By Fei Fei Li 2009 03 01 Please remember this 1000 computer vision papers ge
  • 算法——动态规划算法

    动态规划的核心思路 动态规划的解题核心主要分为两步 第一步 定义问题 有的问题过于抽象 或者过于啰嗦干扰我们解题的思路 我们要做的就是将题干中的问题转化成一系列同类问题的某个解的情况 比如说 题目 求一个数列中最大连续子序列的和 我们要将这
  • tomcat部署项目

    今天总算是把部署tomcat部署项目的几种方式实验了一下 一 1 下载 Tomcat 服务器 官网下载地址 http tomcat apache org 2 启动并部署 Tomcat 服务器 解压 tomcat 安装包到一个非中文目录下 配
  • 微服务架构详解

    一 微服务架构的由来 在微服务架构出现之前 最常用的架构就是单体架构 俗称 一个jar war 包打天下 在一个jar包工程中 采用MVC架构 分为表现层 业务层 数据访问层 所有的业务模块 都放在这个工程中集成 如下图所示 随着软件行业规
  • DS18B20温度传感器

    1 DS18B20 单线数字温度传感器 即 一线器件 其具有独特的优点 采用单总线的接口方式 与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯 单总线具有经济性好 抗干扰能力强 适合于恶劣环境的现场温度测量 测量
  • 【前端】ant design中树形控件的父子节点受控实现

    前言 1 ant design的树形控件里面先设置好checkStrictly属性 即checkable 状态下节点选择完全受控 父子节点选中状态不再关联 这样的话 onCheck函数中的checkedKeys参数打印出来它是一个有chek
  • conda添加清华镜像源

    Anaconda 是一个用于科学计算的 Python 发行版 支持 Linux Mac Windows 包含了众多流行的科学计算 数据分析的 Python 包 Anaconda 安装包可以到 清华镜像源下载anaconda 下载 TUNA
  • 异步赠书:10月Python畅销书升级

    2018年最新活动 免费赠书 1 关注微信号 异步图书 2 邀请10位好友关注10天后 填写下方表单登记信息 即可免费获得异步图书一本 异步社区选书网址 www epubit com 点击登记免费图书邮寄信息 活动已结束 最新活动地址 ht
  • LeetCode 1689. 十-二进制数的最少数目

    如果一个十进制数字不含任何前导零 且每一位上的数字不是 0 就是 1 那么该数字就是一个 十 二进制数 例如 101 和 1100 都是 十 二进制数 而 112 和 3001 不是 给你一个表示十进制整数的字符串 n 返回和为 n 的 十
  • idea 通过访问路径快速定位到Controller方法

    目录 问题原因 解决方案 RestfulToolkit插件 使用方式 windows MAC 扩展 效果展示 问题原因 我们在调试 或者某个接口出现bug首先知道和拿到的一般是接口路径 系统运行久了 模块会很多 接口也会很多 找起来很麻烦
  • Strus2+Spring整合笔记

    1 拷贝Struts2 jar包和Spring jar包到 WEB INF lib目录下 2 配置Strust2核心控制器 配置文件 3 为第三步的Spring提供配置文件 4 添加Struts2 Spring整合的插件包 5 在appCt
  • 虚拟IP是什么?

    要是单讲解虚拟 IP 理解起来很困难 所以干脆把 动态 IP 固定 IP 实体 IP 与虚拟 IP都讲解一下 加深理解和知识扩展 实体 IP 在网络的世界里 为了要辨识每一部计算机的位置 因此有了计算机 IP 位址的定义 一个 IP 就好似
  • 2023-5-16第十六天

    permanent永久的 temporary instruction教授 传授 impart教授 initiate教授 接纳 reside居住于 resident居民 recover恢复 找回 laternate交替的 轮流的 interp
  • 小米官网项目制作——javascript知识分享上

    目录 前言 一 整体架构 二 弹出的盒子 1 定位盒子 2 弹出效果 3 其他细节 三 下拉 展开的切换菜单 1 放置盒子 2 切换盒子 3 添加索引 4 侧边展开的盒子 四 轮播图 1 本体的部件 2 轮播图 3 节流阀 4 其他的细节
  • Docker搭建Seata环境

    Docker搭建Seata环境 添加seata需要的数据库表 直接点击 mysql数据库 oracle数据库 postgresql数据库 为业务数据库也添加一个undo log表 Seata的AT模式下之所以在第一阶段直接提交事务 依赖的是