阿里云分布式事务seata:springcloud-eureka-feign-mybatis-程序员宅基地

技术标签: Java  java  mysql  Intellij idea  分布式事务  seata  

springcloud-eureka-feign-mybatis-seata-client/server

注:来源阿里云开源seata,本人只做修改

概览:seata由服务端及客户端组成,服务端是阿里的项目需要在后台一直运行,客户端只是集成了客户端部分配置文件而已。需要两端同时运行才可以完成分布式事务;

服务端:https://github.com/xieshenace/springcloud-eureka-feign-mybatis-seata-server

客户端:https://github.com/xieshenace/springcloud-eureka-feign-mybatis-seata-client

1.整合seata的demo,此demo都配置好了,拉下来按照步骤,直接可以跑起来观察效果。

2.demo项目整合Seata,主要步骤如下:(可参考进行自己项目整合)

  • 1.下载服务端:原:下载seata-server,放到linux或者自己的window/mac中;
  • 2.下载客户端:此Demo项目(引入配置文件,修改配置文件(注意不要遗漏,可参考下方几个关键步骤))
  • 3.数据源代理设置
  • 4.创建数据库表
  • 5.启动eureka,启动server,启动client(自己的服务比如订单啊,仓库啊,等等等)

关于调用成环和seata-server HA,见最后部分

1.此demo技术选型及版本信息

注册中心:eureka

服务间调用:feign

持久层:mybatis 

数据库:mysql 5.7.20

Springboot:2.1.7.RELEASE

Springcloud:Greenwich.SR2

jdk:1.8 

seata:1.1

使用不同组件,配置情况不同,可参考其他sample(开源地址:https://github.com/seata/seata-samples);

2.demo概况

demo分为四个项目,单独启动。

  • eureka:作为注册中心
  • order:订单服务,用户下单后,会创建一个订单添加在order数据库,同时会扣减库存storage,扣减账户account;
  • storage:库存服务,用户扣减库存;
  • account:账户服务,用于扣减账户余额;

order服务关键代码如下:

  /**
   * 创建订单
   *
   * @param order
   * @return 测试结果: 1.添加本地事务:仅仅扣减库存 2.不添加本地事务:创建订单,扣减库存
   */
  @Override
  @GlobalTransactional(name = "fsp-create-order", rollbackFor = Exception.class)
  public void create(Order order) {
    LOGGER.info("------->交易开始");
    // 本地方法
    orderDao.create(order);
    // 远程方法 扣减库存
    storageApi.decrease(order.getProductId(), order.getCount());
    // 模拟异常情况
    // int i = 1 / 0;
    // 远程方法 扣减账户余额
    LOGGER.info("------->扣减账户开始order中");
    accountApi.decrease(order.getUserId(), order.getMoney());
    LOGGER.info("------->扣减账户结束order中");

    LOGGER.info("------->交易结束");
  }

3.使用步骤

  • 1.拉取本客户端demo代码 git clone xxxx;
  • 2.下载seata-server;
  • 3.执行本demo每个项目下的建表语句,resource下xx.sql文件;(undo_log.sql、account.sql、order.sql、storage.sql);
    注:undo_log.sql需要在项目每个库都需要有一个。如果项目用的一个库则需要一个表就行;
  • 4.seata相关建表语句见下文说明;

4.seata server(服务端)端配置信息修改

seata-server中,/conf目录下,有两个配置文件,需要结合自己的情况来修改:

1.file.conf

里面有事务组配置,锁配置,事务日志存储等相关配置信息,由于此demo使用db存储事务信息,我们这里要修改store中的配置:

## **原本配置**:
## transaction log store
store {
  ## store mode: file、db
  mode = "db"   修改这里,表明事务信息用db存储

  ## file store 当mode=db时,此部分配置就不生效了,这是mode=file的配置
  file {
    dir = "sessionStore"

    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    max-branch-session-size = 16384
    # globe session size , if exceeded throws exceptions
    max-global-session-size = 512
    # file buffer size , if exceeded allocate new buffer
    file-write-buffer-cache-size = 16384
    # when recover batch read size
    session.reload.read_size = 100
    # async, sync
    flush-disk-mode = async
  }

  ## database store  mode=db时,事务日志存储会存储在这个配置的数据库里
  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://116.62.62.26/seat-server"  修改这里
    user = "root"  修改这里
    password = "root"  修改这里
    min-conn = 1
    max-conn = 3
    global.table = "global_table"
    branch.table = "branch_table"
    lock-table = "lock_table"
    query-limit = 100
  }
}

如果mode类型中选择的是db模式则:
由于此demo我们使用db模式存储事务日志,所以,我们要创建三张表:global_table,branch_table,lock_table,建表sql在上面下载的seata-server的/conf/db_store.sql中;

由于存储undo_log是在业务库中,所以在每个业务库中,还要创建undo_log表,建表sql在/conf/db_undo_log.sql中。

由于我自定义了事务组名称,所以这里也做了修改:

service {
  #vgroup->rgroup
  vgroup_mapping.fsp_tx_group = "default"  修改这里,fsp_tx_group这个事务组名称是我自定义的,一定要与client端的这个配置一致!否则会报错!
  #only support single node
  default.grouplist = "127.0.0.1:8091"   此配置作用参考:https://blog.csdn.net/weixin_39800144/article/details/100726116
  #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"
}

其他的可以先使用默认值。
如果,和本demo服务端一致使用的是file模式,则不需要做上面操作,直接使用本Demo服务端配置

## **本Demo服务端file.conf 配置**:
## transaction log store, only used in seata-server
store {
  ## store mode: file、db
  mode = "file"

  ## file store property
  file {
    ## store location dir
    dir = "sessionStore"
    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    maxBranchSessionSize = 16384
    # globe session size , if exceeded throws exceptions
    maxGlobalSessionSize = 512
    # file buffer size , if exceeded allocate new buffer
    fileWriteBufferCacheSize = 16384
    # when recover batch read size
    sessionReloadReadSize = 100
    # async, sync
    flushDiskMode = async
  }
}

2.registry.conf

registry{}中是注册中心相关配置,config{}中是配置中心相关配置。seata中,注册中心和配置中心是分开实现的,是两个东西。

我们这里用eureka作注册中心,所以,只用修改registry{}中的:

## **原本配置**:
registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"  修改这里,指明注册中心使用什么

  nacos {
    serverAddr = "localhost"
    namespace = ""
    cluster = "default"
  }
  eureka {
    serviceUrl = "http://localhost:8761/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"
  }
}

其他的配置可以暂时使用默认值。


## **本demo服务端registry.conf配置**:
registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "file"

  file {
    name = "file.conf"
  }
}

现在已经完成配置修改了,等eureka启动后,就可以启动seata-server了:
如果是在windows下启动seata-server:执行/bin/seata-server.bat即可;
如果是在mac/linux下启动seata-server:sh /bin/seata-server.sh即可;

5.client本Demo(自己项目)端相关配置

1.普通配置

client端的几个服务,都是普通的springboot整合了springCloud组件的正常服务,所以,你需要配置eureka,数据库,mapper扫描等,即使不使用seata,你也需要做,这里不做特殊说明,看代码就好。

2.特殊配置

1.application.yml

以order服务为例,除了常规配置外,这里还要配置下事务组信息:(每个需要分布式的项目中都需要这个,所以都需要配置)

spring:
    application:
        name: order-server
    cloud:
        alibaba:
            seata:
                tx-service-group: fsp_tx_group  
##这个fsp_tx_group自定义命名很重要,server,client都要保持一致

2.file.conf

注意:file.conf、registry.conf每个需要分布式事务的项目中都要有这两个文件,修改好之后直接复制就可以
主要是修改下面:fsp_tx_group 这个名字为自己改的那个名字,要保持统一;

transport {
  # tcp udt unix-domain-socket
  type = "TCP"
  #NIO NATIVE
  server = "NIO"
  #enable heartbeat
  heartbeat = true
  # the client batch send request enable
  enableClientBatchSendRequest = true
  #thread factory for netty
  threadFactory {
    bossThreadPrefix = "NettyBoss"
    workerThreadPrefix = "NettyServerNIOWorker"
    serverExecutorThread-prefix = "NettyServerBizHandler"
    shareBossWorker = false
    clientSelectorThreadPrefix = "NettyClientSelector"
    clientSelectorThreadSize = 1
    clientWorkerThreadPrefix = "NettyClientWorkerThread"
    # netty boss thread size,will not be used for UDT
    bossThreadSize = 1
    #auto default pin or 8
    workerThreadSize = "default"
  }
  shutdown {
    # when destroy server, wait seconds
    wait = 3
  }
  serialization = "seata"
  compressor = "none"
}
service {
  #transaction service group mapping
  
  ########注要是修改fsp_tx_group这个名字############
  vgroupMapping.fsp_tx_group = "default"
  #only support when registry.type=file, please don't set multiple addresses
  default.grouplist = "127.0.0.1:8091"
  #degrade, current not support
  enableDegrade = false
  #disable seata
  disableGlobalTransaction = false
}

client {
  rm {
    asyncCommitBufferLimit = 10000
    lock {
      retryInterval = 10
      retryTimes = 30
      retryPolicyBranchRollbackOnConflict = true
    }
    reportRetryCount = 5
    tableMetaCheckEnable = false
    reportSuccessEnable = false
  }
  tm {
    commitRetryCount = 5
    rollbackRetryCount = 5
  }
  undo {
    dataValidation = true
    logSerialization = "jackson"
    logTable = "undo_log"
  }
  log {
    exceptionRate = 100
  }
}

3.registry.conf

使用eureka做注册中心,仅需要修改eureka的配置即可:

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"

  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3、springCloudConfig
  type = "file"

  file {
    name = "file.conf"
  }
}

其他的使用默认值就好。

3.数据源代理

这个是要特别注意的地方,seata对数据源做了代理和接管,在每个参与分布式事务的服务中,都要做如下配置:

/**
 * 数据源代理
 * @author wangzhongxiang
 */
@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*:/mapper/*.xml"));
        sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
        return sqlSessionFactoryBean.getObject();
    }

}

以及:每个分布式事务的启动类都需要加注解(@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)):比如

/**
 * 订单服务
 * @author wangzhongxiang
 */
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@MapperScan("io.seata.sample.dao")
@EnableDiscoveryClient
@EnableFeignClients
public class OrderServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServerApplication.class, args);
    }
}

6.启动测试

然后可以模拟正常情况,异常情况,超时情况等,观察数据库即可。

这个demo,未做各种优化,如果压测,需要修改和优化一些配置,压测出错了,不一定是seata的锅,自己先排查,再去群里问问。

7.日志

正常情况:

1.order

2019-09-06 15:44:33.536  INFO 53904 --- [io-8080-exec-10] i.seata.tm.api.DefaultGlobalTransaction  : Begin new global transaction [192.168.158.133:8091:2021468859]
2019-09-06 15:44:33.536  INFO 53904 --- [io-8080-exec-10] c.j.order.service.OrderServiceImpl       : ------->交易开始
2019-09-06 15:44:34.376  INFO 53904 --- [io-8080-exec-10] c.j.order.service.OrderServiceImpl       : ------->交易结束
2019-09-06 15:44:34.593  INFO 53904 --- [io-8080-exec-10] i.seata.tm.api.DefaultGlobalTransaction  : [192.168.158.133:8091:2021468859] commit status:Committed
2019-09-06 15:44:35.296  INFO 53904 --- [atch_RMROLE_6_8] i.s.core.rpc.netty.RmMessageListener     : onMessage:xid=192.168.158.133:8091:2021468859,branchId=2021468861,branchType=AT,resourceId=jdbc:mysql://116.62.62.26/seat-order,applicationData=null
2019-09-06 15:44:35.297  INFO 53904 --- [atch_RMROLE_6_8] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.158.133:8091:2021468859 2021468861 jdbc:mysql://116.62.62.26/seat-order null
2019-09-06 15:44:35.297  INFO 53904 --- [atch_RMROLE_6_8] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed

2.storage

2019-09-06 15:44:33.776  INFO 9704 --- [nio-8082-exec-1] c.j.storage.service.StorageServiceImpl   : ------->扣减库存开始
2019-09-06 15:44:34.030  INFO 9704 --- [nio-8082-exec-1] c.j.storage.service.StorageServiceImpl   : ------->扣减库存结束
2019-09-06 15:44:35.422  INFO 9704 --- [atch_RMROLE_5_8] i.s.core.rpc.netty.RmMessageListener     : onMessage:xid=192.168.158.133:8091:2021468859,branchId=2021468864,branchType=AT,resourceId=jdbc:mysql://116.62.62.26/seat-storage,applicationData=null
2019-09-06 15:44:35.423  INFO 9704 --- [atch_RMROLE_5_8] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.158.133:8091:2021468859 2021468864 jdbc:mysql://116.62.62.26/seat-storage null
2019-09-06 15:44:35.423  INFO 9704 --- [atch_RMROLE_5_8] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed

3.account

2019-09-06 15:44:34.039  INFO 36556 --- [nio-8081-exec-5] c.j.account.service.AccountServiceImpl   : ------->扣减账户开始
2019-09-06 15:44:34.039  INFO 36556 --- [nio-8081-exec-5] c.j.account.service.AccountServiceImpl   : ------->扣减账户结束
2019-09-06 15:44:35.545  INFO 36556 --- [atch_RMROLE_3_8] i.s.core.rpc.netty.RmMessageListener     : onMessage:xid=192.168.158.133:8091:2021468859,branchId=2021468867,branchType=AT,resourceId=jdbc:mysql://116.62.62.26/seat-account,applicationData=null
2019-09-06 15:44:35.545  INFO 36556 --- [atch_RMROLE_3_8] io.seata.rm.AbstractRMHandler            : Branch committing: 192.168.158.133:8091:2021468859 2021468867 jdbc:mysql://116.62.62.26/seat-account null
2019-09-06 15:44:35.545  INFO 36556 --- [atch_RMROLE_3_8] io.seata.rm.AbstractRMHandler            : Branch commit result: PhaseTwo_Committed

8.模拟异常

在AccountServiceImpl中模拟异常情况,然后可以查看日志

    /**
     * 扣减账户余额
     * @param userId 用户id
     * @param money 金额
     */
    @Override
    public void decrease(Long userId, BigDecimal money) {
        LOGGER.info("------->扣减账户开始");
        LOGGER.info("------->Account 模拟异常");
        int i = 1 / 0;
        LOGGER.info("------->扣减账户结束");
        accountDao.decrease(userId,money);
    }

9.调用成环

前面的调用链为order->storage->account;
这里测试的成环是指order->storage->account->order,
这里的account服务又会回头去修改order在前面添加的数据。
经过测试,是支持此种场景的。

    /**
     * 扣减账户余额
     * @param userId 用户id
     * @param money 金额
     */
    @Override
    public void decrease(Long userId, BigDecimal money) {
        LOGGER.info("------->扣减账户开始account中");
        //模拟超时异常,全局事务回滚
//        try {
//            Thread.sleep(30*1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        accountDao.decrease(userId,money);
        LOGGER.info("------->扣减账户结束account中");

        //修改订单状态,此调用会导致调用成环
        LOGGER.info("修改订单状态开始");
        String mes = orderApi.update(userId, money.multiply(new BigDecimal("0.09")),0);
        LOGGER.info("修改订单状态结束:{}",mes);
    }

在最初的order会创建一个订单,然后扣减库存,然后扣减账户,账户扣减完,会回头修改订单的金额和状态,这样调用就成环了。

10.seata-server服务端 HA

部署集群,第一台和第二台配置相同,在server端的registry.conf中,注意:

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"
...... 
  eureka {
    serviceUrl = "http://192.168.xx.xx:8761/eureka"  //两台tcc相同,注册中心的地址
    application = "default" //两台tc相同
    weight = "1"  //权重,截至0.9版本,暂时不支持此参数
  }
 ......

注意上述配置和client的配置要一致,2台和多台情况相同。

0.9及之前版本,多tc时,tc会误报异常,此问题0.9之后已经修复,之后的版本应该不会出现此问题。

11.项目整合注意事项(本人整合过程中出现的问题特此记录以防止再踩坑)

  1. springCloud微服务项目最外层pom.xml,不要有任何共有Jar,比如:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.8.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.*****</groupId>
    <artifactId>*****</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>*****</name>
    <description>parent-project</description>
    <packaging>pom</packaging>
    <!--工程模块-->
    <modules>
    <module>*****-common</module>
    <module>*****-eureka-server</module>
    <module>*****-zuul-server</module>
    <module>*****-....</module>
    </modules>
    <!--自定义properties属性-->
    <properties>
    <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>
    <!-- SpringCloud Greenwich.SR2 -->
    <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
    </dependencyManagement>
    <!--定义多环境https://blog.csdn.net/qq_33689414/article/details/81812783-->
    <profiles>
    <profile>
      <id>prod</id>
      <properties>
        <package.environment>prod</package.environment>
      </properties>
    </profile>
    <profile>
      <id>test</id>
      <properties>
        <package.environment>test</package.environment>
      </properties>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
    </profile>
    </profiles>
    <!--插件仅配置公共maven插件,spring-boot-maven-plugin这个插件分别配置到各个微服务避免common打包出现检测到多个main方法问题及微服务工程依赖不到common.jar问题-->
    <build>
    <!--指定打包包名-->
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>8</source>
          <target>8</target>
          <encoding>utf-8</encoding>
        </configuration>
      </plugin>
    </plugins>
    <resources>
      <resource>
        <directory>src/main/resources/</directory>
        <!--开启maven filter功能,打包前将功能中的@xx@变量进行替换,如spring.profiles.active根据当前打包指定的环境进行替换-->
        <filtering>true</filtering>
        <includes>
          <!--指定需要将resources文件进行打包-->
          <include>application.yml</include>
          <include>bootstrap.yml</include>
          <include>mapper/*.xml</include>
          <include>static/**</include>
          <include>application-${package.environment}.yml</include>
          <include>logback.${package.environment}.xml</include>
        </includes>
      </resource>
    </resources>
    </build>
    <!--依赖仓库-->
    <repositories><!-- 代码库,改用aliyun的 -->
    <repository>
      <id>maven-ali</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public//</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    </repositories>
    <!--插件仓库,改用aliyun的-->
    <pluginRepositories>
    <pluginRepository>
      <id>alimaven</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
    </pluginRepositories>
    </project>
    
  2. eureka服务只需要有个spring-cloud-starter-netflix-eureka-server包就可以,其他都不需要,比如:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>com.*******</groupId>
    <artifactId>*******</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>*******-eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>vehicle-eureka-server</name>
    <description>注册中心</description>
    <dependencies>
    <!-- SpringCloud Eureka -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    </dependencies>
    <!--定义多环境https://blog.csdn.net/qq_33689414/article/details/81812783-->
    <profiles>
    <profile>
      <id>prod</id>
      <properties>
        <package.environment>prod</package.environment>
      </properties>
    </profile>
    <profile>
      <id>test</id>
      <properties>
        <package.environment>test</package.environment>
      </properties>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
    </profile>
    </profiles>
    <!--插件仅配置公共maven插件,spring-boot-maven-plugin这个插件分别配置到各个微服务避免common打包出现检测到多个main方法问题及微服务工程依赖不到common.jar问题-->
    <build>
    <!--指定打包包名-->
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <inherited>true</inherited>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
    </build>
    <!--依赖仓库-->
    <repositories><!-- 代码库,改用aliyun的 -->
    <repository>
      <id>maven-ali</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public//</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    </repositories>
    <!--插件仓库,改用aliyun的-->
    <pluginRepositories>
    <pluginRepository>
      <id>alimaven</id>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
    </pluginRepositories>
    </project>
    

    以及不要配置什么file.conf数据源之类的东西;(除了这个服务其他涉及到业务回滚的服务都需要配置)

  3. file.conf、registry.conf与application.yml整合,首先更改seata pom为:

    <!-- Spring Cloud Seata -->
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-seata</artifactId>
      <version>2.2.0.RELEASE</version>
      <exclusions>
        <exclusion>
          <groupId>io.seata</groupId>
          <artifactId>seata-spring-boot-starter</artifactId>
        </exclusion>
        <exclusion>
          <artifactId>seata-all</artifactId>
          <groupId>io.seata</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>io.seata</groupId>
      <artifactId>seata-spring-boot-starter</artifactId>
      <version>1.1.0</version>
    </dependency>
    <dependency>
      <groupId>io.seata</groupId>
      <artifactId>seata-all</artifactId>
      <version>1.1.0</version>
    </dependency>
    
  4. 启动类不需要加excu**排除自动代理,因为我用的是hikari所以新增如下类:

    @Configuration
    public class DataSourceConfigure {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource dataSource() {
    return new HikariDataSource();
    }
    }
    

    新增application.yml内容为:

    seata:
    enabled: true
    application-id: user
    tx-service-group: ksc_tx_group #自定义名字保持统一
    enable-auto-data-source-proxy: false
    service:
    vgroupMapping:
      ksc_tx_group: seata-server #默认default,这个是seate的名字,改了之后需要改服务端registry.conf 中eureka  application = "seata-server",保持统一
    enable-degrade: false
    disable-global-transaction: false
    registry:
    type: eureka
    eureka:
      service-url: http://localhost:8888/eureka/
    weight: 1
    config:
    type: file
    

    出现问题多看看github例子即可解决,新东西版本差别很大注意区别

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_17213067/article/details/105099689

智能推荐

零基础学习Hadoop_hadoop零基础怎么学-程序员宅基地

文章浏览阅读3.9k次,点赞4次,收藏31次。原文:http://www.aboutyun.com/thread-6780-1-1.html 零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易。在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结。所以索性就自己学习了。整个过程整理一下,给大家参考,欢迎讨论,共同学习。从一开始什么都不懂,到能够搭建集群,开发。整个过程,只要有Linux基础,虚拟机化和ja_hadoop零基础怎么学

mongodb分片集群搭建(6.0.10版)_mongo 6.0.10部署-程序员宅基地

文章浏览阅读319次。mongodb分片集群搭建最新版(6.0.10)_mongo 6.0.10部署

华中科技大学计算机博士好考吗,【经验】谈谈我的三次华科考博经历--申请版主加分...-程序员宅基地

文章浏览阅读3.8k次。又到一年考博报名时,回想自己的三次华科考博经历,以成功开始,以失败结束。今天把其间的辛酸和喜悦,经验和收获贴出来,希望给对后来者有一些借鉴和指导价值。记得第一次考华科的时候是2009年,硕士(心血管方向)即将毕业,本着一颗红心两种准备的思想,计划考个博试试,万一能考取也给自己毕业时多一份选择。在网上看了几所学校的招生简章,发觉华科协和医院和上海交大心血管方向专业基础课考的都是生理学,本人对生理相对..._华科计算机申博

微信公众平台深度开发JAVA版第一季 30.菜单6-程序员宅基地

文章浏览阅读110次。{"button":[{ "type": "click", "name": "说明001", "key": "001" },{ "type": "view", "name": "说明002", "url":...

Nacos启动失败 ead cluster conf fail nacos\conf\cluster.conf_read cluster conf fail-程序员宅基地

文章浏览阅读626次。出现这个问题,是因为直接./bin/startup.sh没有设置为单机启动单机启动_read cluster conf fail

Firewalld共享上网及本地yum仓库搭建步骤-程序员宅基地

文章浏览阅读141次。分享Firewalld共享上网及本地yum仓库搭建步骤 Firewalld共享上网1.服务端操作(有外网的服务器)1.开启防火墙并加入开机自启动[root@linuxprobe ~]# systemctl start firewalld[root@linuxprobe ~]# systemctl enable firewalld2.移除默认所有人能访问ssh的规则[root@linuxprobe ~]# firewall-cmd --remove-service=ssh -

随便推点

Qt 设置窗口居中显示和窗体大小_qt中ui设计的界面怎么让运行中放大且在中间-程序员宅基地

文章浏览阅读1.4k次。设置窗口居中显示方法一:在窗口(QWidget类及派生类)的构造函数中添加如下代码:#include //.......QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以move((desktop->width() - this->width())/2, (desktop->hei_qt中ui设计的界面怎么让运行中放大且在中间

oracle 字符串split转换成列表格_oracle 字符串转表格 sqlsplit-程序员宅基地

文章浏览阅读5k次。create or replace type strsplit_type as table of VARCHAR2(32676)create or replace function strsplit(p_value varchar2, p_split varchar2 := ',')--usage: sele_oracle 字符串转表格 sqlsplit

小文一篇,说说:where、:has和:is的特殊性吧_has where-程序员宅基地

文章浏览阅读5.2k次,点赞15次,收藏4次。css推出的:where、:has和:is伪类满足了我对“逻辑化CSS”的简单幻想。简单说下,假如你有这么一个需求:在响应式页面中,你需要判断头部元素中是否具有某一个图标,以决定 Top 文字的样式(间距、对齐方向等)。不知道各位以前是怎么实现的。为了“性能考虑”,笔者通常是通过“动态 class”,用 js 操作元素样式。那时候就想,如果css中就可以去判断元素就好了!但是从张大佬那得知,我这种想法是“子元素选择”,就是父元素根据子元素调整,这样可能会带来重绘这样严重的影响。_has where

python对办公文档处理_reader = get_reader(filepath) sheetname = reader.g-程序员宅基地

文章浏览阅读4.7k次,点赞2次,收藏8次。python对办公文档处理Pillow库进行图像文件处理openpyxl库对Excel表格的自动化处理Python-docx库对Word的自动化处理PyPDF2库对PDF的自动化处理python-pptx库对pptx的自动化处理win32com库自动化处理_reader = get_reader(filepath) sheetname = reader.get_sheets()

nginx域名重定向(自动补全www)及未解决问题_输入域名不能补全-程序员宅基地

文章浏览阅读4.3k次。所用系统为centos6;为解决输入网址xxx.com如何自动跳转到www.xxx.com问题解决方法:进入本机nginx域名配置文件,文件位置:/usr/local/nginx/conf/vhost/www.xxx.com.conf在该配置文件的最后添加如下代码server { server_name xxx.com; rewrite ^(.*)$ http://www.x_输入域名不能补全

CSS与其选择器_css 和-程序员宅基地

文章浏览阅读316次。CSS 概述 CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与表现分离的问题 外部样式表可以极大提高工作效率 外部样式表通常存储在 CSS 文件中 多个样式定义可层叠为一 CSS 语法CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明。selector {declaration1; de_css 和

推荐文章

热门文章

相关标签