从seata的最简单模式file模式开始,学习下seata。开始之前先启动下seata TC,启动脚本如下:
version: "3"
services:
seata-server:
image: seataio/seata-server:latest
hostname: seata-server
ports:
- "8091:8091"
- "7091:7091"
environment:
- SEATA_PORT=8091
- STORE_MODE=file
- SEATA_CONFIG_NAME=file:/root/seata-config/registry
看到server started说明启动成功了
% docker compose -f ./learn/seata/exp1/docker-compose.yaml up
WARN[0000] Found orphan containers ([exp1_benthos_1 exp1_app_1]) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
[+] Running 1/1
⠿ Container exp1-seata-server-1 Created 0.3s
Attaching to exp1-seata-server-1
exp1-seata-server-1 | apm-skywalking not enabled
exp1-seata-server-1 | 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=/
exp1-seata-server-1 | OpenJDK 64-Bit Server VM warning: Cannot open file /root/logs/seata/seata_gc.log due to No such file or directory
exp1-seata-server-1 |
exp1-seata-server-1 | ███████╗███████╗ █████╗ ████████╗ █████╗
exp1-seata-server-1 | ██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔══██╗
exp1-seata-server-1 | ███████╗█████╗ ███████║ ██║ ███████║
exp1-seata-server-1 | ╚════██║██╔══╝ ██╔══██║ ██║ ██╔══██║
exp1-seata-server-1 | ███████║███████╗██║ ██║ ██║ ██║ ██║
exp1-seata-server-1 | ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
exp1-seata-server-1 |
exp1-seata-server-1 |
exp1-seata-server-1 | 15:06:52.305 INFO --- [ main] [ta.config.ConfigurationFactory] [ load] [] : load Configuration from :Spring Configuration
exp1-seata-server-1 | 15:06:52.398 INFO --- [ main] [ta.config.ConfigurationFactory] [ buildConfiguration] [] : load Configuration from :Spring Configuration
exp1-seata-server-1 | 15:06:53.580 INFO --- [ main] [seata.server.ServerApplication] [ logStarting] [] : Starting ServerApplication using Java 1.8.0_342 on seata-server with PID 1 (/seata-server/classes started by root in /seata-server)
exp1-seata-server-1 | 15:06:53.585 INFO --- [ main]
exp1-seata-server-1 | 15:07:02.862 INFO --- [ main] [io.seata.server.ServerRunner ] [ run] [] : seata server started in 1035 millSeconds
seata-examples里面的api,实现了官方最简单的例子
我们开始一步步实现它:首先启动mysql
% docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
2023-09-16 14:47:41+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.40-1.el7 started.
2023-09-16 14:47:41+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
然后创建对应的几个表
% mysql -uroot -p123456 -h127.0.0.1
mysql> create database fescar;
Query OK, 1 row affected (0.03 sec)
mysql> use fescar;
Database changed
mysql> 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 AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `stock_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` (`commodity_code`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
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',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
mysql> 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;
Query OK, 0 rows affected (0.02 sec)
找到目录seata-example/seata-samples/api/pom.xml修改下slf4j版本
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>2.0.9</version>
</dependency>
接着修改下配置文件src/main/resources/jdbc.properties
jdbc.account.url=jdbc:mysql://127.0.0.1:3306/fescar?useSSL=false&serverTimezone=UTC
jdbc.account.username=root
jdbc.account.password=123456
jdbc.account.driver=com.mysql.jdbc.Driver
# stock db config
jdbc.stock.url=jdbc:mysql://127.0.0.1:3306/fescar?useSSL=false&serverTimezone=UTC
jdbc.stock.username=root
jdbc.stock.password=123456
jdbc.stock.driver=com.mysql.jdbc.Driver
# order db config
jdbc.order.url=jdbc:mysql://127.0.0.1:3306/fescar?useSSL=false&serverTimezone=UTC
jdbc.order.username=root
jdbc.order.password=123456
jdbc.order.driver=com.mysql.jdbc.Driver
然后编译
mvn build && mvn install
执行下
% java --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/sun.net.util=ALL-UNNAMED -jar target/seata-samples-api-1.1.0.jar
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.23.0.2:8091:18450265429737473
rollback trx, cause: data negative, xid is 172.23.0.2:8091:18450265429737473
事务回滚了,查询下数据库,money和stock都是初始值,说明实现了一致性。因为单价是200,买5个的话账户余额不足。
mysql> select * from order_tbl;
Empty set (0.00 sec)
mysql> select * from account_tbl;
+----+---------+-------+
| id | user_id | money |
+----+---------+-------+
| 2 | U100001 | 999 |
+----+---------+-------+
1 row in set (0.00 sec)
mysql> select * from stock_tbl;
+----+----------------+-------+
| id | commodity_code | count |
+----+----------------+-------+
| 2 | C00321 | 100 |
+----+----------------+-------+
1 row in set (0.00 sec)
我们把数量改成4,测试下
% java --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/sun.net.util=ALL-UNNAMED -jar target/seata-samples-api-1.1.0.jar
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.23.0.2:8091:18450265429737493
96
199
true
事务执行成功了,并且数据库也符合我们的预期
mysql> select * from stock_tbl;
+----+----------------+-------+
| id | commodity_code | count |
+----+----------------+-------+
| 6 | C00321 | 96 |
+----+----------------+-------+
1 row in set (0.00 sec)
mysql> select * from order_tbl;
+----+---------+----------------+-------+-------+
| id | user_id | commodity_code | count | money |
+----+---------+----------------+-------+-------+
| 6 | U100001 | C00321 | 4 | 800 |
+----+---------+----------------+-------+-------+
1 row in set (0.00 sec)
mysql> select * from account_tbl;
+----+---------+-------+
| id | user_id | money |
+----+---------+-------+
| 6 | U100001 | 199 |
+----+---------+-------+
1 row in set (0.00 sec)
至此,我们体验完了最简单的文件模式。
本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!