细心的盆友可能已经发现了,我们的跨行转账并没有保证数据一致性,比如小明扣除了100,但是因为各种问题小红在添加100金额的时候遇到了异常,这个时候数据就出现不一致性
我们可以选择seata来进行分布式事务杜绝这种现象的发生
之前的教程:https://www.cnblogs.com/leafstar/p/17641407.html
1.我使用的是seata1.7版本,可以从官网很简单下载到,不同版本配置可能略有不同
2.修改seata配置conf/application.yml
我的配置如下:
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:
# nacos配置
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace:
group: SEATA_GROUP
username:
password:
context-path:
data-id: seataServer.properties
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
registry:
# nacos配置
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
cluster: default
username:
password:
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login
3.通过bin目录下的脚本启动seata
4.在需要发起全局事务的数据库中创建undo_log表,语句如下
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- Table structure for undo_log
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`branch_id` bigint NOT NULL,
`xid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`context` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `ux_undo_log`(`xid` ASC, `branch_id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- Records of undo_log
SET FOREIGN_KEY_CHECKS = 1;
将seata目录下seata\script\server\db的mysql.sql脚本文件导入数据库中,最终效果如下
5.仅在需要发起全局事务的服务中添加依赖
6.仅在需要发起全局事务的服务中添加以下配置即可
seata:
enabled: true
application-id: ccxi-abc
tx-service-group: ccxi_tx_group
service:
vgroup-mapping:
ccxi_tx_group: default
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: public
group: SEATA_GROUP
application: seata-server
7.在nacos中添加seataServer.properties配置如下图
配置如下
#Transaction storage configuration, only for the server.
store.mode=db
store.lock.mode=db
store.session.mode=db
#These configurations are required if the `store mode` is `db`.
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/bank1?useSSL=false&useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
将数据库信息改成自己的信息
8.在准备开启全局事务的接口下添加注解
9.报错如下,execute executeAutoCommitTrue error:[xid:192.168.74.1:8091:8413149769213006417]get table meta failed, please check whether the table `account` exists.
主要是因为数据表中没有设置主键,在此为了简单,我们选择将name变成主键
10.重启项目并调用转账接口,可以看到seata的服务面板显示如下
11现在我们来模拟小红收款异常,故意在这里抛出异常并等待20秒,重启服务
12.调用转账接口
可以看到,undo_log已经被写入一条数据,抛出异常后,这条数据就没了,同时我们对小明的转账修改也被撤销
13.等待的20秒内,小明数据被修改
抛出异常后,小明的数据又被改回来了
14.seata控制台显示回滚成功
15.至此,我们完成了分布式事务的简单使用,这个系列的实战教程也就结束了
手机扫一扫
移动阅读更方便
你可能感兴趣的文章