SpringCloud集成Seata2.0实现分布式事务

SpringCloud集成Seata2.0实现分布式事务


关于seata的原理和实现逻辑网上很多就不再赘述l。干脆直接一点,直接讲该如何实现分布式事务。
1、下载seata
https://seata.apache.org/zh-cn/unversioned/download/seata-server/
下载2.0版本
2、在数据库中新建seata数据库
在这里插入图片描述
在seata数据库中执行文件路径下对应的数据库脚本,这里用的是mysql
在这里插入图片描述

关键点来了:

在这里插入图片描述
编辑seata的配置文件

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
    nacos:
      server-addr: 192.168.5.40:8848
      namespace: b137693a-b922-4384-a8f0-cc9d0ab35fd9
      group: SEATA_GROUP
      username:
      password:
      context-path:
      data-id: seataServer.properties
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      server-addr: 192.168.5.40:8848
      group: SEATA_GROUP
      namespace: b137693a-b922-4384-a8f0-cc9d0ab35fd9
      cluster: default
      username:
      password:
      context-path:
  data-source-proxy-mode: AT
  server:
    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
    max-commit-retry-timeout: -1
    max-rollback-retry-timeout: -1
    rollback-retry-timeout-unlock-enable: false
    enable-check-auth: true
    enable-parallel-request-handle: true
    enable-parallel-handle-branch: false
    retry-dead-threshold: 130000
    xaer-nota-retry-timeout: 60000
    enableParallelRequestHandle: true
    recovery:
      committing-retry-period: 1000
      async-committing-retry-period: 1000
      rollbacking-retry-period: 1000
      timeout-retry-period: 1000
    undo:
      log-save-days: 7
      log-delete-period: 86400000
    session:
      branch-async-queue-size: 5000 #branch async remove queue size
      enable-branch-async-remove: false #enable to asynchronous remove branchSession
  store:
    # support: file 、 db 、 redis 、 raft
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true
      user: root
      password: root
      min-conn: 10
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      query-limit: 1000
      max-wait: 5000
  metrics:
    enabled: false
    registry-type: compact
    exporter-list: prometheus
    exporter-prometheus-port: 9898
  transport:
    rpc-tc-request-timeout: 15000
    enable-tc-server-batch-send-response: false
    shutdown:
      wait: 3
    thread-factory:
      boss-thread-prefix: NettyBoss
      worker-thread-prefix: NettyServerNIOWorker
      boss-thread-size: 1
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login,/metadata/v1/**

如果和我一样用的nacos,改一下地址server-addr,group,和namespace就行。
db:中改为你的数据库配置

在这里插入图片描述

nacos中增加配置
在这里插入图片描述

# 存储模式
store.mode=db
 
store.db.datasource=druid
store.db.dbType=mysql
# 需要根据mysql的版本调整driverClassName
# mysql8及以上版本对应的driver:com.mysql.cj.jdbc.Driver
# mysql8以下版本的driver:com.mysql.jdbc.Driver
store.db.driverClassName=com.mysql.cj.jdbc.Driver
# 注意根据生产实际情况调整参数host和port
store.db.url=jdbc:mysql://127.0.0.1:3306/seata
# 数据库用户名密码
store.db.user=root
store.db.password=root
# 微服务里配置与这里一致
service.vgroupMapping.fsp_tx_group=default
service.vgroupMapping.fsp_tx_group=default
service.vgroupMapping.fsp_tx_group=default
service.vgroupMapping.default=default

在这里插入图片描述
双击启动seata
在这里插入图片描述
在这里插入图片描述
在nacos中可以看到seata已经注册了。

 <!--seata分布式事务-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>

在服务中引用上面的依赖,这个依赖重写了fegin调用保证了多个服务之间seata的XID一致。
服务配置文件yml中增加seata配置

seata:
  registry:
    type: nacos
    nacos:
      server-addr: 192.168.5.40:8848
      namespace: b137693a-b922-4384-a8f0-cc9d0ab35fd9
      group: SEATA_GROUP
      application: seata-server
  # 事务组名称
  tx-service-group: default
  service:
    # 事务组与tc集群的映射关系
    vgroup-mapping:
      # default - tc服务的集群名称
      default: default
  enabled: true

在业务数据库中(不是seata数据库,而是微服务的业务数据库)
建测试表进行测试。
在这里插入图片描述
创建undo_log表给seata用

CREATE TABLE `undo_log` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `branch_id` bigint NOT NULL,
  `xid` varchar(100) COLLATE utf8mb4_general_ci NOT NULL,
  `context` varchar(128) COLLATE utf8mb4_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) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=570 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

服务A代码,t2会报空指针

@GlobalTransactional(rollbackFor = Exception.class)
    @GetMapping(value = "/test")
    public ResultBean test() {
        System.out.println("事务id---------------------->" + RootContext.getXID());
        Test1 t1 = new Test1();
        t1.setName("user插入");
        testMapper.insert(t1);
        System.out.println("user插入Success====================================");
        externalFeignClient.exSeataTest();
        Test1 t2 = null;
        t2.getName();
        return ResultBean.success();
    }

服务B

  @GlobalTransactional(rollbackFor = Exception.class)
    @GetMapping(value = "/exSeataTest")
    public ResultBean exSeataTest(){
        System.out.println("事务id---------------------->" + RootContext.getXID());
        Test1 t1 = new Test1();
        t1.setName("ext插入");
        testMapper.insert(t1);
        System.out.println("ext插入Success====================================");
        return ResultBean.success();
    }

服务A在调用服务B,插入两条数据后,会报空指针,回滚插入的两条数据。

只要在调用远程的服务接口上加上注解就可以实现分布式事务了,被调用的接口上也加@GlobalTransactional(rollbackFor = Exception.class)注解

http://localhost:7091/端口是seata的可视化界面。密码在seata的配置文件中配置,我配置的是seata seata。

需要注意的几点:
1、被调用的服务的异常不能被全局异常器捕获,异常被捕获后,seata会认为没有发送异常,无法进行事务回滚,原理和@Transaction注解失效原理差不多。解决方法是通过校验调用其他服务的返回码是不是正常,不正常手动抛出一个异常,让seata取感知,从而回滚多个服务之间的事务。

   ResultBean res = externalFeignClient.exSeataTest();
        if (200 != res.getCode()) {
            throw new BusinessException();
        }

2、服务A和服务B的yml中seata配置要一样

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Seata 2.0是一款开源的分布式事务解决方案,用于解决分布式系统中的事务一致性问题。它提供了大规模分布式事务的管理和协调能力,支持多种主流的数据库和中间件,如MySQL、Oracle、Redis等。下面是关于Seata 2.0下载的相关介绍: 首先,要下载Seata 2.0,我们可以通过官方的GitHub仓库进行下载。在GitHub上搜索Seata,并找到官方仓库。然后,在仓库的首页可以找到最新版本的下载链接。点击链接后,你可以选择下载相应的文件,比如源码包或者二进制包。 其次,如果你希望直接下载预编译好的二进制包,可以找到release或者releases标签,点击查看已发布的版本列表。在列表中找到你想要下载的版本号,并点击进入对应的版本页面。在这个页面中,你可以找到下载链接,点击即可开始下载。 另外,Seata 2.0还提供了多种语言版本的SDK,包括Java、Go、Node.js等。如果你需要使用某个特定语言的SDK,可以在仓库的首页或版本页面中找到相关链接,点击即可下载。 最后,如果你对Seata 2.0的下载有任何问题或疑问,可以在官方仓库的Issues页面中提问,或者参考官方文档和社区论坛获取更多帮助。 总结一下,要下载Seata 2.0,可以通过官方GitHub仓库找到最新版本的下载链接,选择下载源码包或者二进制包,并根据需求选择相应的语言SDK。同时,如果有任何问题,可以通过官方渠道获取帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值