SpringCloud教程 | 第八篇: 使用seata处理分布式事务

1、参考程序员江小北

2、打算降低nacos版本,先学通再看看升级到高版本nacos能不能正常使用。

3、nacos用1.4.1,正常启动单机版的了

4、seata用2.0.0

我看江小北说用的1.4.0的seata,但是图片中的目录文件都找不到,倒是在2.0.0的seata中找到了,于是使用2.0.0的seata

4.1导入seata数据库

4.2、在源码目录下打开GitBash,输入shnacos-config.sh,导入完成后,可在nacos中查看到所有配置;

4.3、 修改seata配置文件,修改注册中心及配置中心为nacos,配置nacos地址;

参考江小北的,发现启动不了服务了。

搜了一圈资料,发现有个模板文件可以参考:

application.yml文件最终内容如下:

#  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.

server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${log.home:${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:
  config:
    # support: nacos, consul, apollo, zk, etcd3
    # type: nacos
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace:
      group: SEATA_GROUP
      username:
      password:
      context-path:
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key:
      #secret-key:
      data-id: seataServer.properties
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    # type: file
    type: nacos
    preferred-networks: 30.240.*
    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:
  #store:
    # support: file 、 db 、 redis 、 raft
    #mode: file
  #  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,/metadata/v1/**

4.4、启动seata

点击该文件启动seata

seat服务注册到nacos中了。

5、在spring cloud框架下搞3个微服务,使用spring boot启动微服务、使用feign调用其它服务。

在Idea工具中建立一个maven项目,pom.xml作为父项目,

然后在该项目下,新建3个module,结构如下图所示:

参考某某某的文章,pom.xml会有依赖冲突,启动遇到了一些问题,搜了一些资料,较新版本会牵扯到各组件有没有跟进适配上,会有问题。

spring boot / spring cloud换成了较低的版本,然后通过maven pom.xml的Dependency Analyzer排除依赖解决了冲突,然后服务可以正常启动了。

要先建立3个库,库表结构截图如下:

SQL语句如下:

account_tbl.sql

-- ----------------------------
-- Table structure for account_tbl
-- ----------------------------
DROP TABLE IF EXISTS account_tbl;
CREATE TABLE account_tbl  (
  id int(11) NOT NULL AUTO_INCREMENT,
  user_id varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  money int(11) NULL DEFAULT 0,
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11111112 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of account_tbl
-- ----------------------------
INSERT INTO account_tbl VALUES (11111111, '2', 1000);

order_tbl.sql

-- ----------------------------
-- Table structure for order_tbl
-- ----------------------------
DROP TABLE IF EXISTS order_tbl;
CREATE TABLE order_tbl  (
  id int(11) NOT NULL AUTO_INCREMENT,
  user_id varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  commodity_code varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  count int(11) NULL DEFAULT 0,
  money int(11) NULL DEFAULT 0,
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1006 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

storage_tbl.sql

-- ----------------------------
-- Table structure for storage_tbl
-- ----------------------------
DROP TABLE IF EXISTS storage_tbl;
CREATE TABLE storage_tbl  (
  id int(11) NOT NULL AUTO_INCREMENT,
  commodity_code varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  count int(11) NULL DEFAULT 0,
  create_time datetime(0) NULL DEFAULT NULL,
  update_time datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 77 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of storage_tbl
-- ----------------------------
INSERT INTO storage_tbl VALUES (1, 'iphone11', 100, '2020-09-28 16:55:51', '2020-10-14 16:13:21');

5.1、关于如何生成代码,可以参考如下工程:

代码工程放在guthub上:GitHub - veminhe/mybatis-plus-generator

5.2、代码解说如下:

seata-service-account是用户服务,用户下单,就会记录一条订单记录,然后更新用户的余额(这里是减1)。

seata-service-order是订单服务,用户下单后,该服务记录一条订单记录,同时扣减库存。

seata-service-storage是库存服务,用户下单购买了几件物品,对应物品的库存就减几。

正常情况下不加第36行这行代码,逻辑是正常的。如果加了第36行代码,则在有seata分布式事务管理的情况下是可以保证正常的事务性,否则不能保证事务性。

启动这3个服务,访问:localhost:10000/accountTbl/insertOrder

验证符合预期。

代码放在github上:GitHub - veminhe/seata-demo2

记得下载下来将目录中的2去掉,应该是seata-demo,个人github网络出问题了,搞了个seata-demo2重新上传了。

5.3、使用时遇到的错,参考某某某的配置,这里这样配置,启动服务报错了,

要改成seata的config.txt文件里的default_tx_group

也就是配置到nacos中的对应值

昨天启动好的,逻辑都验证完了。今天启动报错了,报错如下:

2024-07-15 15:53:55.141 ERROR 1116 --- [eoutChecker_2_1] i.s.c.r.netty.NettyClientChannelManager  : 0101 can not connect to 192.168.42.65:8091 cause:can not register RM,err:can not connect to services-server.

io.seata.common.exception.FrameworkException: can not register RM,err:can not connect to services-server.
	at io.seata.core.rpc.netty.NettyClientChannelManager.doConnect(NettyClientChannelManager.java:225) ~[seata-all-1.4.0.jar:1.4.0]
	at io.seata.core.rpc.netty.NettyClientChannelManager.acquireChannel(NettyClientChannelManager.java:107) ~[seata-all-1.4.0.jar:1.4.0]
	at io.seata.core.rpc.netty.NettyClientChannelManager.reconnect(NettyClientChannelManager.java:189) ~[seata-all-1.4.0.jar:1.4.0]
	at io.seata.core.rpc.netty.AbstractNettyRemotingClient$1.run(AbstractNettyRemotingClient.java:114) [seata-all-1.4.0.jar:1.4.0]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_371]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_371]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_371]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_371]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_371]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_371]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-all-4.1.63.Final.jar:4.1.63.Final]
	at java.lang.Thread.run(Thread.java:750) [na:1.8.0_371]

2024-07-15 15:53:55.141  INFO 1116 --- [eoutChecker_2_1] i.s.c.r.netty.NettyClientChannelManager  : will connect to 192.168.42.65:8091
2024-07-15 15:53:55.141  INFO 1116 --- [eoutChecker_2_1] i.s.c.rpc.netty.RmNettyRemotingClient    : RM will register :jdbc:mysql://127.0.0.1:3306/db_account
2024-07-15 15:53:55.141  INFO 1116 --- [eoutChecker_2_1] i.s.core.rpc.netty.NettyPoolableFactory  : NettyPool create channel to transactionRole:RMROLE,address:192.168.42.65:8091,msg:< RegisterRMRequest{resourceIds='jdbc:mysql://127.0.0.1:3306/db_account', applicationId='seata-service-account', transactionServiceGroup='default_tx_group'} >
2024-07-15 15:54:05.114 ERROR 1116 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager  : 0304 register RM failed.

应该是我换了一下网络造成的。重新确认不用换网络之后,启动服务,不报错了。

5.4、验证

5.4.1、成功场景

访问http://localhost:10000/accountTbl/insertOrder

执行成功,控制台有打印相关的日志

查看数据库的数据,对应正确

5.4.2、有异常失败回滚场景

停止StorageApp服务,然后取消int a = 1/0;的注释,启动StorageApp服务

调用接口http://localhost:10000/accountTbl/insertOrder

报错了。控制台有打印相关的日志

查看数据库的数据,没有任何改动。

验证通过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值