Seata 是什么? | Apache SeataSeata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
https://seata.apache.org/zh-cn/docs/overview/what-is-seata/新人文档 | Apache SeataSeata分TC、TM和RM三个角色,TC(Server端)为单独服务端部署,TM和RM(Client端)由业务系统集成。
https://seata.apache.org/zh-cn/docs/v2.0/ops/deploy-guide-beginner


简单理解上面的流程:
三个角色:TC、TM、RM
1、TM向TC申请全局事务,成功后生成XID
2、XID在微服务上下文中传递
3、RM向TC注册分支事务,和XID进行关联绑定管辖
4、TM向TC发起全局的提交或回滚
5、TC调度XID管辖范围内的全部分支事务进行提交或回滚
TC作为服务,需要seata数据库,及固定的表(4张表:branch_table、distributed_lock、global_table、local_table)
每个RM需要一张undo_log表
1 准备seata数据库
# 生成mysql容器 mysql-seata
docker run -d \\ -p 2306:3306 \\ -v /server/seata/conf:/etc/mysql/conf.d \\ -v /server/seata/data:/var/lib/mysql \\ -e MYSQL_ROOT_PASSWORD=123456 \\ –name mysql-seata \\ mysql:8.0.30
# 建库、建表
CREATE DATABASE seata;
USE seata;
建表sql
— ——————————– The script used when storeMode is 'db' ——————————–
— the table to store GlobalSession data
CREATE 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 data
CREATE 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 data
CREATE 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);
2 准备业务数据库
# 生成mysql容器 mysql-seata-biz
docker run -d \\ -p 2307:3306 \\ -v /server/seataBiz/conf:/etc/mysql/conf.d \\ -v /server/seataBiz/data:/var/lib/mysql \\ -e MYSQL_ROOT_PASSWORD=123456 \\ –name mysql-seata-biz \\ mysql:8.0.30
准备seata_account、seata_order、seata_stroage业务数据库
# 建order库、表
CREATE DATABASE seata_order;
CREATE TABLE t_order(
`id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` BIGINT(11) DEFAULT NULL COMMENT '用户id',
`product_id` BIGINT(11)DEFAULT NULL COMMENT '产品id',
`count` INT(11) DEFAULT NULL COMMENT '数量',
`money` DECIMAL(11,0) DEFAULT NULL COMMENT '金额',
`status` INT(1) DEFAULT NULL COMMENT '订单状态: 0:创建中; 1:已完结'
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
SELECT * FROM t_order;
# 建stroage库、表
CREATE DATABASE seata_storage;
CREATE TABLE t_storage(
`id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`product_id` BIGINT(11) DEFAULT NULL COMMENT '产品id',
`total` INT(11) DEFAULT NULL COMMENT '总库存',
`used` INT(11) DEFAULT NULL COMMENT '已用库存',
`residue` INT(11) DEFAULT NULL COMMENT '剩余库存'
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO t_storage(`id`,`product_id`,`total`,`used`,`residue`)VALUES('1','1','100','0','100');
SELECT * FROM t_storage;
# 建account库、表
CREATE DATABASE seata_account;
CREATE TABLE t_account(
`id` BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'id',
`user_id` BIGINT(11) DEFAULT NULL COMMENT '用户id',
`total` DECIMAL(10,0) DEFAULT NULL COMMENT '总额度',
`used` DECIMAL(10,0) DEFAULT NULL COMMENT '已用账户余额',
`residue` DECIMAL(10,0) DEFAULT '0' COMMENT '剩余可用额度'
)ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO t_account(`id`,`user_id`,`total`,`used`,`residue`)VALUES('1','1','1000','0','1000');
SELECT * FROM t_account;
3个库分表建undo_log表
– for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(128) 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(6) NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

3 准备nacos(注册中心)
docker pull nacos/nacos-server:v2.2.3

# 创建nacos容器
docker run –name nacos -e MODE=standalone -p 8848:8848 -p 9848:9848 -d nacos/nacos-server:v2.2.3

4 TC作为server单独部署
https://github.com/apache/incubator-seata/releases/tag/v2.0.0
docker pull seataio/seata-server:2.0.0

启动(先确认已启动nacos)
docker run -d –name seata-server \\ -p 8091:8091 \\ -p 7091:7091 \\ -v /seata/config/resources:/seata-server/resources \\ seataio/seata-server:2.0.0
# 默认配置问题
1 先启动临时seata-server-temp,让容器自动生成默认的配置文件
docker run -d –name seata-server-temp \\ -p 8091:8091 \\ -p 7091:7091 \\ seataio/seata-server:2.0.0
2 再将配置文件拷贝到指定目录下
mkdir -p seata/config/resources
docker cp seata-server-temp:/seata-server/resources/. seata/config/resources/
3 删除临时容器,重新执行指定的创建容器命令
docker rm seata-server-temp
docker run -d –name seata-server \\ -p 8091:8091 \\ -p 7091:7091 \\ -v /seata/config/resources:/seata-server/resources \\ seataio/seata-server:2.0.0
到/seata/config/resources下修改配置文件 application.yml
启动后报错:
docker logs seata-server apm-skywalking not enabled JMX disabled Affected JVM parameters: -Dlog.home=/root/logs/seata -server -Dloader.path=/lib -Xmx2048m -Xms2048m -Xss640k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m -XX:-OmitStackTraceInFastThrow -XX:-UseAdaptiveSizePolicy -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/root/logs/seata/java_heapdump.hprof -XX:+DisableExplicitGC -Xloggc:/root/logs/seata/seata_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -Dio.netty.leakDetectionLevel=advanced -Dapp.name=seata-server -Dapp.pid=1 -Dapp.home=/ -Dbasedir=/ OpenJDK 64-Bit Server VM warning: Cannot open file /root/logs/seata/seata_gc.log due to No such file or directory
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000080000000, 2147483648, 0) failed; error='Cannot allocate memory' (errno=12) # # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 2147483648 bytes for committing reserved memory. # An error report file with more information is saved as: # /seata-server/hs_err_pid1.log
修复—- 启动参数加上内存限制:
docker run -d
–name seata-server -p 8091:8091 -p 7091:7091
-e JMX_OPTS="-Xmx512m -Xms512m"
-v /seata/config/resources:/seata-server/resources seataio/seata-server:2.0.0
seata-server启动成功后注册到nacos中

至此环境搭建完成,后面可以结合@GlobalTransactional+配置文件试试效果
网硕互联帮助中心





评论前必须登录!
注册