SEATA 分布式事务入门DEMO

Simple Extensible Autonomous Transacation Architecture,seata是简单的、可扩展、自主性高的分布式架构

SEATA Server Configure

因我们使用正式的1.0.0-GA 版本,网上大多数找到的说明都是0.X版本,有不少变动,比如,在server中取消了db_store.sql的脚本,如找不到相关内容,可以通过源码来查找,比如db脚本源码:mysql db script

  1. 下载 seata-server
  2. 创建数据库(seata),可自定义,在file.conf中要用到。
    -- -------------------------------- The script used when storeMode is 'db' --------------------------------
    -- the table to store GlobalSession data
    CREATE TABLE IF NOT EXISTS `global_table`
    (
        `xid`                       VARCHAR(128) NOT NULL,
        `transaction_id`            BIGINT,
        `status`                    TINYINT      NOT NULL,
        `application_id`            VARCHAR(32),
        `transaction_service_group` VARCHAR(32),
        `transaction_name`          VARCHAR(128),
        `timeout`                   INT,
        `begin_time`                BIGINT,
        `application_data`          VARCHAR(2000),
        `gmt_create`                DATETIME,
        `gmt_modified`              DATETIME,
        PRIMARY KEY (`xid`),
        KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),
        KEY `idx_transaction_id` (`transaction_id`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8;
    
    -- the table to store BranchSession data
    CREATE TABLE IF NOT EXISTS `branch_table`
    (
        `branch_id`         BIGINT       NOT NULL,
        `xid`               VARCHAR(128) NOT NULL,
        `transaction_id`    BIGINT,
        `resource_group_id` VARCHAR(32),
        `resource_id`       VARCHAR(256),
        `branch_type`       VARCHAR(8),
        `status`            TINYINT,
        `client_id`         VARCHAR(64),
        `application_data`  VARCHAR(2000),
        `gmt_create`        DATETIME,
        `gmt_modified`      DATETIME,
        PRIMARY KEY (`branch_id`),
        KEY `idx_xid` (`xid`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8;
    
    -- the table to store lock data
    CREATE TABLE IF NOT EXISTS `lock_table`
    (
        `row_key`        VARCHAR(128) NOT NULL,
        `xid`            VARCHAR(96),
        `transaction_id` BIGINT,
        `branch_id`      BIGINT       NOT NULL,
        `resource_id`    VARCHAR(256),
        `table_name`     VARCHAR(32),
        `pk`             VARCHAR(36),
        `gmt_create`     DATETIME,
        `gmt_modified`   DATETIME,
        PRIMARY KEY (`row_key`),
        KEY `idx_branch_id` (`branch_id`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8;
  3. 编辑file.conf配置文件
    service {
      #transaction service group mapping
      vgroup_mapping.sunrise_tx_group = "default"
      #only support when registry.type=file, please don't set multiple addresses
      default.grouplist = "127.0.0.1:8091"
      #disable seata
      disableGlobalTransaction = false
      #degrade current not support
      enableDegrade = false
      #disable
      disable = false
      #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
      max.commit.retry.timeout = "-1"
      max.rollback.retry.timeout = "-1"
    }
    
    ## transaction log store, only used in seata-server
    store {
      ## store mode: file、db
      mode = "db"
    
      ## file store property
      file {
        ## store location dir
        dir = "sessionStore"
      #degrade current not support
      enableDegrade = false
      #disable
      disable = false
      #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
      max.commit.retry.timeout = "-1"
      max.rollback.retry.timeout = "-1"
    }
    
    ## transaction log store, only used in seata-server
    store {
      ## store mode: file、db
      mode = "db"
    
      ## file store property
      file {
        ## store location dir
        dir = "sessionStore"
      }
    
      ## database store property
      db {
        ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
        datasource = "dbcp"
        ## mysql/oracle/h2/oceanbase etc.
        db-type = "mysql"
        driver-class-name = "com.mysql.jdbc.Driver"
        url = "jdbc:mysql://localhost:3306/seata"
        user = "wr"
        password = "wr"
        min-conn = 1
        max-conn = 3
        global.table = "global_table"
        branch.table = "branch_table"
        lock-table = "lock_table"
        query-limit = 100
      }
    }
  4. 编辑conf/regiester.conf
    registry {
      # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
      # 更改1
      type = "eureka"
    
      nacos {
        serverAddr = "localhost"
        namespace = ""
        cluster = "default"
      }
      eureka {
         # 更改2
        serviceUrl = "http://localhost:21001/eureka"
        application = "default"
        weight = "1"
      }
      redis {
        serverAddr = "localhost:6379"
        db = "0"
      }
      zk {
        cluster = "default"
        serverAddr = "127.0.0.1:2181"
        session.timeout = 6000
        connect.timeout = 2000
      }
      consul {
        cluster = "default"
        serverAddr = "127.0.0.1:8500"
      }
      etcd3 {
        cluster = "default"
        serverAddr = "http://localhost:2379"
      }
      sofa {
        serverAddr = "127.0.0.1:9603"
        application = "default"
        region = "DEFAULT_ZONE"
        datacenter = "DefaultDataCenter"
        cluster = "default"
        group = "SEATA_GROUP"
        addressWaitTime = "3000"
      }
      file {
        name = "file.conf"
      }
    }
    
    config {
      # file、nacos 、apollo、zk、consul、etcd3
      type = "file"
    
      nacos {
        serverAddr = "localhost"
        namespace = ""
      }
      consul {
        serverAddr = "127.0.0.1:8500"
      }
      apollo {
        app.id = "seata-server"
        apollo.meta = "http://192.168.1.204:8801"
      }
      zk {
        serverAddr = "127.0.0.1:2181"
        session.timeout = 6000
        connect.timeout = 2000
      }
      etcd3 {
        serverAddr = "http://localhost:2379"
      }
      file {
        name = "file.conf"
      }
    }

    本次实现,我们还没有添加configration的时候,因此只需要更改register块中的相关属性即可,在后续我们实现了nacos config之后,再同步更新这里。

  5. 启动服务端

    [[email protected] /usr/local/geekplus/server/seata]# bin/seata-server.sh 


    eureka中看到如下8091端口的服务之后,即启动seata-server正常!

Client Configure

AT Model

需要在每一个业务库中添加数据表undo_log.

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;

Broadway-Demo

使用Springboot项目有一个小规律,我叫它为使用三部曲。
broadway-ws-tally-service项目为例:

  • 第一步:加依赖

            <!--seata-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-seata</artifactId>
                <version>2.1.0.RELEASE</version>
                <exclusions>
                    <exclusion>
                        <artifactId>seata-all</artifactId>
                        <groupId>io.seata</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>io.seata</groupId>
                <artifactId>seata-all</artifactId>
                <version>1.0.0</version>
            </dependency>
  • 第二步:开启注解
    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

    在这里需要说明一下,我们需要排除掉SpringBoot默认自动注入的DataSourceAutoConfigurationBean, 因为SEATA是基于数据源拦截来实现的分布式事务,因此,我们需要自定义数据源配置信息:

    package com.geekplus.broadway.ws.tally.application;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import io.seata.rm.datasource.DataSourceProxy;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import javax.sql.DataSource;
    
    @Configuration
    public class DataSourceConfiguration {
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource druidDataSource(){
            DruidDataSource druidDataSource = new DruidDataSource();
            return druidDataSource;
        }
    
        @Primary
        @Bean("dataSource")
        public DataSourceProxy dataSource(DataSource druidDataSource){
            return new DataSourceProxy(druidDataSource);
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSourceProxy);
            sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources("classpath*:/com/geekplus/*.xml"));
            sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
            return sqlSessionFactoryBean.getObject();
        }
    }

    该配置类,一般放在与启动类相同的目录即可!

  • 第三部:改配置
    spring:
      cloud:
        alibaba:
          seata:
            tx-service-group: sunrise_tx_group 

    TIPS:
    tx-service-group 一定要server,client都要保持一致,否则能坑死你!
    tx-service-group 一定要server,client都要保持一致,否则能坑死你!
    tx-service-group 一定要server,client都要保持一致,否则能坑死你!

以上三步是大多数SpringBoot 项目的通用做法,当然我们的SEATA暂时还不是那么完善,配置信息目前还不支持在application.yml中配置完全,因此,我们需要2个核心的client 配置文件file.confregister.conf.

  • file.conf 该文件主要是用于连接RM的,我们只需要关注上面所说的tx-service-group就行,其他配置默认就可以。

    transport {
      # tcp udt unix-domain-socket
      type = "TCP"
      #NIO NATIVE
      server = "NIO"
      #enable heartbeat
      heartbeat = true
      # the client batch send request enable
      enable-client-batch-send-request = true
      #thread factory for netty
      thread-factory {
        boss-thread-prefix = "NettyBoss"
        worker-thread-prefix = "NettyServerNIOWorker"
        server-executor-thread-prefix = "NettyServerBizHandler"
        share-boss-worker = false
        client-selector-thread-prefix = "NettyClientSelector"
        client-selector-thread-size = 1
        client-worker-thread-prefix = "NettyClientWorkerThread"
        # netty boss thread size,will not be used for UDT
        boss-thread-size = 1
        #auto default pin or 8
        worker-thread-size = 8
      }
      shutdown {
        # when destroy server, wait seconds
        wait = 3
      }
      serialization = "seata"
      compressor = "none"
    }
    
    service {
      #transaction service group mapping
      vgroup_mapping.sunrise_tx_group = "default"
      #only support when registry.type=file, please don't set multiple addresses
      default.grouplist = "127.0.0.1:8091"
      #disable seata
      disableGlobalTransaction = false
    }
    
    client {
      rm {
        async.commit.buffer.limit = 10000
        lock {
          retry.internal = 10
          retry.times = 30
          retry.policy.branch-rollback-on-conflict = true
        }
        report.retry.count = 5
        table.meta.check.enable = false
        report.success.enable = true
      }
      tm {
        commit.retry.count = 5
        rollback.retry.count = 5
      }
      undo {
        data.validation = true
        log.serialization = "jackson"
        log.table = "undo_log"
      }
      log {
        exceptionRate = 100
      }
      support {
        # auto proxy the DataSource bean
        spring.datasource.autoproxy = false
      }
     }
  • register.conf该文件是用于指定注册中心相关配置的,它有2个核心block
    • registry块
      此模板表明我们的注册中心使用类型,需要根据type设置来同步更新使用的配置信息,比如我们使用的eureka,因此我们更新eureka.serviceUrl="http://172.16.1.187:21001/eureka".
    • config 块
      该模块用来设置我们的配置中心相关配置(此处后续更新,我们会选择apollo
    registry {
      # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
      type = "eureka"
    
      nacos {
        serverAddr = "localhost"
        namespace = ""
        cluster = "default"
      }
      eureka {
        serviceUrl = "http://172.16.1.187:21001/eureka"
        application = "default"
        weight = "1"
      }
      redis {
        serverAddr = "localhost:6379"
        db = "0"
      }
      zk {
        cluster = "default"
        serverAddr = "127.0.0.1:2181"
        session.timeout = 6000
        connect.timeout = 2000
      }
      consul {
        cluster = "default"
        serverAddr = "127.0.0.1:8500"
      }
      etcd3 {
        cluster = "default"
        serverAddr = "http://localhost:2379"
      }
      sofa {
        serverAddr = "127.0.0.1:9603"
        application = "default"
        region = "DEFAULT_ZONE"
        datacenter = "DefaultDataCenter"
        cluster = "default"
        group = "SEATA_GROUP"
        addressWaitTime = "3000"
      }
      file {
        name = "file.conf"
      }
    }
    
    config {
      # file、nacos 、apollo、zk、consul、etcd3
      type = "file"
    
      nacos {
        serverAddr = "localhost"
        namespace = ""
      }
      consul {
        serverAddr = "127.0.0.1:8500"
      }
      apollo {
        app.id = "seata-server"
        apollo.meta = "http://192.168.1.204:8801"
      }
      zk {
        serverAddr = "127.0.0.1:2181"
        session.timeout = 6000
        connect.timeout = 2000
      }
      etcd3 {
        serverAddr = "http://localhost:2379"
      }
      file {
        name = "file.conf"
      }
    }

原文地址:https://www.cnblogs.com/zhangpan1244/p/12198147.html

时间: 2024-09-29 22:10:26

SEATA 分布式事务入门DEMO的相关文章

Java事务处理全解析(八)——分布式事务入门例子(Spring+JTA+Atomikos+Hibernate+JMS)

在本系列先前的文章中,我们主要讲解了JDBC对本地事务的处理,本篇文章将讲到一个分布式事务的例子. 请通过以下方式下载github源代码: git clone https://github.com/davenkin/jta-atomikos-hibernate-activemq.git 本地事务和分布式事务的区别在于:本地事务只用于处理单一数据源事务(比如单个数据库),分布式事务可以处理多种异构的数据源,比如某个业务操作中同时包含了JDBC和JMS或者某个操作需要访问多个不同的数据库. Java

微服务、分库分表、分布式事务管理、APM链路跟踪性能分析演示项目

好多年没发博,最近有时间整理些东西,分享给大家. 所有内容都在github项目liuzhibin-cn/my-demo中,基于SpringBoot,演示Dubbo微服务 + Mycat, Sharding-Proxy分库分表 + Seata分布式事务管理 + ZipKin, SkyWalking, PinPoint性能分析链路跟踪APM工具,有详细文档,可以快速运行 演示项目架构 运行演示项目 package.sh为打包脚本: sh package.sh:最简单运行方式,使用单个MySQL数据库

阿里分布式事务seata入门(采坑)

1. 阿里分布式事务seata入门(采坑) 1.1. 前言 seata是feascar改名而来,这是阿里在19年年初开源出来的分布式事务框架,当初刚出来的时候就想研究下了,一直拖到了现在,目前是0.8.0版本,看版本就知道这还是个比较新的项目,但现在已经有上万个Star了,可见阿里的影响力.但是虽然有阿里背书,该挖坑还得挖,它宣称集成它比较简单,导致的是现在它的文档优点残缺不全,好几个文档标题点进去都没内容,不知道为什么删了,可能是更新比较快,文档跟不上节奏索性删了[手动滑稽] 1.2. 快速开

Spring Cloud同步场景分布式事务怎样做?试试Seata

一.概述 在微服务架构下,虽然我们会尽量避免分布式事务,但是只要业务复杂的情况下这是一个绕不开的问题,如何保证业务数据一致性呢?本文主要介绍同步场景下使用Seata的AT模式来解决一致性问题. Seata是 阿里巴巴 开源的 一站式分布式事务解决方案 中间件,以 高效 并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题 ? 二.Seata介绍 整体事务逻辑是基于 两阶段提交 的模型,核心概念包括以下3个角色: TM:事务的发起者.用来告诉 TC,全局事务的开始,提交,回滚.

Spring Cloud Alibaba | 微服务分布式事务之Seata

Spring Cloud Alibaba | 微服务分布式事务之Seata 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Greenwich.SR2 Spring CLoud Alibaba:2.1.0.RELEASE 1. 概述 在构建微服务的过程中,不管是使用什么框架.组件来构建,都绕不开一个问题,跨服务的业务操作如何保持数据一致性. 2. 什么是分布式事务? 首先,设想一个传统的单体应用,无论多少内部调用,最后终归是在同一

出席分布式事务Seata 1.0.0 GA典礼

摘自:https://www.cnblogs.com/sanshengshui/p/12094894.html 前言 图中那个红衣服的就是本人 什么是分布式事务 分布式事务就是指事务的参与者.支持事务的服务器.资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上. 简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败. 本质上来说,分布式事务就是为了保证不同数据库的数据一致性. 分布式事

分布式事务框架-seata初识

摘自:https://www.cnblogs.com/iceggboom/p/12144570.html 分布式事务框架-seata初识 一.事务与分布式事务 事务,在数据库中指的是操作数据库的最小单位,往大了看,事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. 那为什么会有分布式事务呢?单机事务是通过将操作限制在一个会话内通过数据库本身的锁以及日志来实现ACID.因为引入了分布式架构,所以事务的参与者.支持事务的服务器.资源服务器以及事务管理器

Spring Boot 集成 Seata 解决分布式事务问题

文章首发于公众号<程序员果果>地址 : https://mp.weixin.qq.com/s/aDhGG3Y2t4lPYetK01Wmxg seata 简介 Seata 是 阿里巴巴2019年开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务.在 Seata 开源之前,Seata 对应的内部版本在阿里内部一直扮演着分布式一致性中间件的角色,帮助阿里度过历年的双11,对各业务进行了有力的支撑.经过多年沉淀与积累,2019.1 Seata 正式宣布对外开源 .目前

Springboot入门之分布式事务管理

springboot默认集成事务,只主要在方法上加上@Transactional即可. 分布式事务一种情况是针对多数据源,解决方案这里使用springboot+jta+atomikos来解决 一.pom文件 <groupId>cn.iponkan</groupId>    <artifactId>springboot-jsp</artifactId>    <version>1.0-SNAPSHOT</version>     <