微服务集成seata完成分布式事务,解决数据不一致问题

细心的盆友可能已经发现了,我们的跨行转账并没有保证数据一致性,比如小明扣除了100,但是因为各种问题小红在添加100金额的时候遇到了异常,这个时候数据就出现不一致性

我们可以选择seata来进行分布式事务杜绝这种现象的发生

seata官网:https://seata.io/zh-cn/docs/overview/what-is-seata.html

之前的教程: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: #  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,/**/*.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目录下seatascriptserverdb的mysql.sql脚本文件导入数据库中,最终效果如下

微服务集成seata完成分布式事务,解决数据不一致问题

 

5.仅在需要发起全局事务的服务中添加依赖

<dependency>     <groupId>io.seata</groupId>     <artifactId>seata-spring-boot-starter</artifactId>     <version>1.4.2</version>  </dependency>

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配置如下图

微服务集成seata完成分布式事务,解决数据不一致问题

配置如下

#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.在准备开启全局事务的接口下添加注解

微服务集成seata完成分布式事务,解决数据不一致问题

 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的服务面板显示如下

微服务集成seata完成分布式事务,解决数据不一致问题

 11现在我们来模拟小红收款异常,故意在这里抛出异常并等待20秒,重启服务

微服务集成seata完成分布式事务,解决数据不一致问题

 

12.调用转账接口

微服务集成seata完成分布式事务,解决数据不一致问题

可以看到,undo_log已经被写入一条数据,抛出异常后,这条数据就没了,同时我们对小明的转账修改也被撤销

13.等待的20秒内,小明数据被修改

微服务集成seata完成分布式事务,解决数据不一致问题

抛出异常后,小明的数据又被改回来了

微服务集成seata完成分布式事务,解决数据不一致问题

 14.seata控制台显示回滚成功

微服务集成seata完成分布式事务,解决数据不一致问题

 15.至此,我们完成了分布式事务的简单使用,这个系列的实战教程也就结束了

 16.教程列表如下

1.SpringBoot+Mybatis-Plus+Mysql的保姆级搭建

https://www.cnblogs.com/leafstar/p/17638741.html

2.Mybatis-Plus+Nacos配置中心和服务发现保姆级教程

https://www.cnblogs.com/leafstar/p/17638782.html

3.Mybatis-Plus+Nacos+Dubbo进行远程RPC调用保姆级教程

https://www.cnblogs.com/leafstar/p/17638933.html

4.微服务集成redis并通过redis实现排行榜的功能

https://www.cnblogs.com/leafstar/p/17641358.html

5.微服务集成RabbitMq保姆级教程

https://www.cnblogs.com/leafstar/p/17641407.html

6.微服务集成seata完成分布式事务,解决数据不一致问题

https://www.cnblogs.com/leafstar/p/17641498.html

 源码:https://gitee.com/leafstart/spring-cloud-bank.git

 

发表评论

评论已关闭。

相关文章