[Spring Cloud Alibaba] Seata distributed transaction

Posted by at0mic on Fri, 31 Dec 2021 19:58:03 +0100

[Spring Cloud Alibaba] Seata distributed transaction

1,Spring Cloud Alibaba Seata

Seata is an open source distributed transaction solution, which is committed to providing high-performance and easy-to-use distributed transaction services under the microservice architecture. Before the opening of Seata, the corresponding internal version of Seata has been playing the role of distributed consistency Middleware in Alibaba economy, helping the economy survive the double 11 over the years and providing strong support for BU businesses. After years of precipitation and accumulation, commercial products have been sold in Alibaba cloud and financial cloud. On January 2019, in order to create a more perfect technological ecology and inclusive technological achievements, Seata officially announced open source. In the future, Seata will help its technology more reliable and complete in the form of community construction

Seata's official website, https://seata.io/zh-cn/
Spring Cloud quickly integrates with Seata, https://github.com/seata/seata-samples/blob/master/doc/quick-integration-with-spring-cloud.md

This article uses Seata's AT mode
Business requirements: place order - > reduce inventory - > deduct balance - > change order status

2. Service public content

Public content needs to be added in each module, except application YML is a little different. All other configurations are the same

(1) Correlation dependency

The dependencies of the three modules are the same

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>${spring-cloud-starter-openfeign.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-boot-starter.version}</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <dependency>
            <groupId>com.spring4all</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
            <version>${swagger-spring-boot-starter.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

(2)application.yml

The three services need to modify the port, database name and other applications The YML configuration files are the same

modularportEndpointdatabase
spring-cloud-alibaba-boot-seata-account80079007alibaba-seata-account
spring-cloud-alibaba-boot-seata-order80089008alibaba-seata-order
spring-cloud-alibaba-boot-seata-storage80099009alibaba-seata-storage
# Application configuration
server:
  port: 8007

# Endpoint monitoring
management:
  endpoint:
    health:
      show-details: always
  endpoints:
    jmx:
      exposure:
        include: '*'
    web:
      exposure:
        include: '*'
  server:
    port: 9007

spring:
  # apply name
  application:
    name: spring-cloud-alibaba-boot-seata-account
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/alibaba-seata-account?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    serialization:
      write-dates-as-timestamps: false
  # Microservice configuration
  cloud:
    # Nacos configuration
    nacos:
      discovery:
        namespace: sandbox-configuration
        password: nacos
        server-addr: localhost:8848
        username: nacos
    alibaba:
      # Seata configuration
      seata:
        tx-service-group: tellsea_tx_group

# MybatisPlus configuration
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath*:mapper/**/*Mapper.xml

(3)file.conf,registry.conf

In the bin directory of seata you downloaded, copy it to the resource directory of the project

And in file It is added in the conf file, which is the same level as the store, because there is no in the default configuration file

service {
  #vgroup->rgroup
  vgroupMapping.tellsea_tx_group = "default"
  #only support single node
  default.grouplist = "127.0.0.1:8091"
  #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"
}

(4)AjaxResult

The Ajax results of the three services are the same

package cn.tellsea.entity;


import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;

/**
 * Common return value
 *
 * @author Tellsea
 * @date 2021/12/31
 */
public class AjaxResult<T> extends HashMap<String, Object> {
    /**
     * Status code
     */
    public static final String CODE_TAG = "code";
    /**
     * Return content
     */
    public static final String MSG_TAG = "msg";
    /**
     * data object
     */
    public static final String DATA_TAG = "data";
    private static final long serialVersionUID = 1L;

    /**
     * Initialize a newly created Ajax result object to represent an empty message.
     */
    public AjaxResult() {
    }

    /**
     * Initialize a newly created Ajax result object
     *
     * @param code Status code
     * @param msg  Return content
     */
    public AjaxResult(int code, String msg) {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
    }

    /**
     * Initialize a newly created Ajax result object
     *
     * @param code Status code
     * @param msg  Return content
     * @param data data object
     */
    public AjaxResult(int code, String msg, T data) {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
        if (!ObjectUtils.isEmpty(data)) {
            super.put(DATA_TAG, data);
        }
    }

    /**
     * Return success message
     *
     * @return Success message
     */
    public static AjaxResult<Void> success() {
        return AjaxResult.success("Operation succeeded");
    }

    /**
     * Return success data
     *
     * @return Success message
     */
    public static <T> AjaxResult<T> success(T data) {
        return AjaxResult.success("Operation succeeded", data);
    }

    /**
     * Return success message
     *
     * @param msg Return content
     * @return Success message
     */
    public static AjaxResult<Void> success(String msg) {
        return AjaxResult.success(msg, null);
    }

    /**
     * Return success message
     *
     * @param msg  Return content
     * @param data data object
     * @return Success message
     */
    public static <T> AjaxResult<T> success(String msg, T data) {
        return new AjaxResult(HttpStatus.OK.value(), msg, data);
    }

    /**
     * Return error message
     *
     * @return
     */
    public static AjaxResult<Void> error() {
        return AjaxResult.error("operation failed");
    }

    /**
     * Return error message
     *
     * @param msg Return content
     * @return Warning message
     */
    public static AjaxResult<Void> error(String msg) {
        return AjaxResult.error(msg, null);
    }

    /**
     * Return error message
     *
     * @param msg  Return content
     * @param data data object
     * @return Warning message
     */
    public static <T> AjaxResult<T> error(String msg, T data) {
        return new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, data);
    }

    /**
     * Return error message
     *
     * @param code Status code
     * @param msg  Return content
     * @return Warning message
     */
    public static AjaxResult<Void> error(int code, String msg) {
        return new AjaxResult(code, msg, null);
    }

    public Integer getCode() {
        return (Integer) super.get(CODE_TAG);
    }

    public String getMsg() {
        return (String) super.get(MSG_TAG);
    }

    public T getData() {
        return (T) super.get(DATA_TAG);
    }
}

(5) Code generation

Use the code generator to generate controller, service, serviceImpl, mapper and mapper XML file, which will not be used. See the previous article

[Spring Cloud Alibaba] Mybatis Plus code generator: https://mp.weixin.qq.com/s/9OZRbIqhLEOhH3QKEJWwPg

If you do not know something, you can leave a message on WeChat official account. https://gitee.com/tellsea/spring-cloud-alibaba-learn

(6) Create module database

3. Set up account service

Create the spring cloud Alibaba boot Seata account module. First complete the account services in Section 2

Control layer

package cn.tellsea.controller;


import cn.tellsea.entity.AjaxResult;
import cn.tellsea.service.IBizAccountService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

/**
 * <p>
 * Account table front end controller
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
@RestController
@RequestMapping("/bizAccount")
public class BizAccountController {

    @Autowired
    private IBizAccountService accountService;

    @ApiOperation("Deduction account")
    @PostMapping("/account/decrease")
    AjaxResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money) {
        return accountService.decrease(userId, money);
    }
}

Interface layer

package cn.tellsea.service;

import cn.tellsea.entity.AjaxResult;
import cn.tellsea.entity.BizAccount;
import com.baomidou.mybatisplus.extension.service.IService;

import java.math.BigDecimal;

/**
 * <p>
 * Account table service
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
public interface IBizAccountService extends IService<BizAccount> {

    /**
     * Deduction account
     *
     * @param userId
     * @param money
     * @return
     */
    AjaxResult decrease(Long userId, BigDecimal money);
}

Interface implementation layer

package cn.tellsea.service.impl;

import cn.tellsea.entity.AjaxResult;
import cn.tellsea.entity.BizAccount;
import cn.tellsea.mapper.BizAccountMapper;
import cn.tellsea.service.IBizAccountService;
import cn.tellsea.utils.BigDecimalUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * <p>
 * Account table service implementation class
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
@Slf4j
@Service
public class BizAccountServiceImpl extends ServiceImpl<BizAccountMapper, BizAccount> implements IBizAccountService {

    @Override
    public AjaxResult decrease(Long userId, BigDecimal money) {
        log.info("------->Start of deduction balance");
        //Simulation timeout exception, global transaction rollback
        //Pause the thread for a few seconds
        //try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); }
        BizAccount account = baseMapper.selectById(userId);
        account.setResidue(BigDecimalUtils.subtract(account.getResidue(), money));
        account.setUsed(BigDecimalUtils.add(account.getUsed(), money));
        baseMapper.updateById(account);
        log.info("------->End of deduction balance");
        return AjaxResult.success("Balance deducted successfully");
    }
}

The account module needs to add a BigDecimalUtils tool class

package cn.tellsea.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Amount calculation tool
 *
 * @author Tellsea
 * @date 2021/12/31
 */
public class BigDecimalUtils {

    /**
     * Save 2 decimal places by default
     */
    private static int POINTS = 2;

    /**
     * Default carry mode
     */
    private static RoundingMode MODE = RoundingMode.CEILING;


    /**
     * plus
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        if (a == null) {
            a = BigDecimal.valueOf(0.00);
        }
        if (b == null) {
            b = BigDecimal.valueOf(0.00);
        }
        return computer(1, a, b, POINTS, MODE);
    }

    public static BigDecimal add(BigDecimal a, BigDecimal b, int points, RoundingMode mode) {
        if (a == null) {
            a = BigDecimal.valueOf(0.00);
        }
        if (b == null) {
            b = BigDecimal.valueOf(0.00);
        }
        return computer(1, a, b, points, mode);
    }

    /**
     * reduce
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal subtract(BigDecimal a, BigDecimal b) {
        if (a == null) {
            a = BigDecimal.valueOf(0.00);
        }
        if (b == null) {
            b = BigDecimal.valueOf(0.00);
        }
        return computer(2, a, b, POINTS, MODE);
    }

    public static BigDecimal subtract(BigDecimal a, BigDecimal b, int points, RoundingMode mode) {
        if (a == null) {
            a = BigDecimal.valueOf(0.00);
        }
        if (b == null) {
            b = BigDecimal.valueOf(0.00);
        }
        return computer(2, a, b, points, mode);
    }


    /**
     * ride
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal multiply(BigDecimal a, BigDecimal b) {
        return computer(3, a, b, POINTS, MODE);
    }

    /**
     * except
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal divide(BigDecimal a, BigDecimal b) {
        if (b.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.valueOf(0.00);
        }
        return computer(4, a, b, POINTS, MODE);
    }

    public static BigDecimal divide(BigDecimal a, BigDecimal b, int points, RoundingMode mode) {
        return computer(4, a, b, points, mode);
    }

    /**
     * computing method
     *
     * @param type   1-Add 2 - subtract 3 - multiply 4 - divide
     * @param a
     * @param b
     * @param points
     * @param mode
     * @return
     */
    public static BigDecimal computer(int type, BigDecimal a, BigDecimal b, int points, RoundingMode mode) {
        BigDecimal rs;
        switch (type) {
            case 1:
                rs = a.add(b).setScale(points, mode);
                break;
            case 2:
                rs = a.subtract(b).setScale(points, mode);
                break;
            case 3:
                rs = a.multiply(b).setScale(points, mode);
                break;
            default:
                rs = a.divide(b, points, mode);
                break;
        }
        return rs;
    }


    public BigDecimal multiply(BigDecimal a, BigDecimal b, int points, RoundingMode mode) {
        return computer(3, a, b, points, mode);
    }

}

Add annotation to startup class

@EnableDiscoveryClient
@EnableFeignClients
@MapperScan("cn.tellsea.mapper")

4. Build order service

Create the spring cloud Alibaba boot Seata order module. First complete the account services in Section 2
Control layer

package cn.tellsea.controller;

import cn.tellsea.entity.AjaxResult;
import cn.tellsea.entity.BizOrder;
import cn.tellsea.service.IBizOrderService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 * Order form front end controller
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
@RestController
@RequestMapping("/bizOrder")
public class BizOrderController {

    @Autowired
    private IBizOrderService orderService;

    @ApiOperation("Create order")
    @GetMapping("/createOrder")
    public AjaxResult createOrder(BizOrder entity) {
        return orderService.createOrder(entity);
    }
}

Interface layer

package cn.tellsea.service;

import cn.tellsea.entity.AjaxResult;
import cn.tellsea.entity.BizOrder;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * Order form service class
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
public interface IBizOrderService extends IService<BizOrder> {

    /**
     * Create order
     *
     * @param entity
     * @return
     */
    AjaxResult createOrder(BizOrder entity);
}

Interface implementation layer

package cn.tellsea.service.impl;

import cn.tellsea.entity.AjaxResult;
import cn.tellsea.entity.BizOrder;
import cn.tellsea.feignclient.FeignBizAccountService;
import cn.tellsea.feignclient.FeignBizStorageService;
import cn.tellsea.mapper.BizOrderMapper;
import cn.tellsea.service.IBizOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 * Order table service implementation class
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
@Slf4j
@Service
public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> implements IBizOrderService {

    @Autowired
    private FeignBizAccountService accountService;
    @Autowired
    private FeignBizStorageService storageService;

    @Override
    public AjaxResult createOrder(BizOrder entity) {
        log.info("------>Start new order");
        baseMapper.insert(entity);
        log.info("------>The order micro service starts to call inventory and deduct count");
        storageService.decrease(entity.getProductId(), entity.getCount());
        log.info("------>The order micro service starts to call inventory and deduct end");
        log.info("------>The order micro service starts to call the account and deduct money");
        accountService.decrease(entity.getUserId(), entity.getMoney());
        log.info("------>The order micro service starts to call the account and deduct end");
        log.info("------>Start modifying order status");
        entity.setStatus(2);
        baseMapper.updateById(entity);
        log.info("------>Finished modifying order status");
        log.info("------>Order completed");
        return AjaxResult.success("checkout success ");
    }
}

Add annotation to startup class

@EnableDiscoveryClient
@EnableFeignClients
@MapperScan("cn.tellsea.mapper")

Add account service remote calling interface

package cn.tellsea.feignclient;

import cn.tellsea.entity.AjaxResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;

/**
 * Account services
 *
 * @author Tellsea
 * @date 2021/12/31
 */
@FeignClient("spring-cloud-alibaba-boot-seata-account")
public interface FeignBizAccountService {

    /**
     * Deduction of account balance
     *
     * @param userId
     * @param money
     * @return
     */
    @PostMapping("/bizAccount/account/decrease")
    AjaxResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money);
}

Add inventory service remote call interface

package cn.tellsea.feignclient;

import cn.tellsea.entity.AjaxResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Inventory service
 *
 * @author Tellsea
 * @date 2021/12/31
 */
@FeignClient(value = "spring-cloud-alibaba-boot-seata-storage")
public interface FeignBizStorageService {

    /**
     * Deduct inventory
     *
     * @param productId
     * @param count
     * @return
     */
    @PostMapping("/bizStorage/storage/decrease")
    AjaxResult decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count);
}

5. Build inventory service

Create the spring cloud Alibaba boot Seata storage module. First complete the account services in Section 2
Control layer

package cn.tellsea.controller;


import cn.tellsea.entity.AjaxResult;
import cn.tellsea.service.IBizStorageService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 * Inventory table front controller
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
@RestController
@RequestMapping("/bizStorage")
public class BizStorageController {

    @Autowired
    private IBizStorageService storageService;

    @ApiOperation("Deduct inventory")
    @RequestMapping("/storage/decrease")
    public AjaxResult decrease(Long productId, Integer count) {
        return storageService.decrease(productId, count);
    }
}

Interface layer

package cn.tellsea.service;

import cn.tellsea.entity.AjaxResult;
import cn.tellsea.entity.BizStorage;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * Inventory table service class
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
public interface IBizStorageService extends IService<BizStorage> {

    /**
     * Deduct inventory
     *
     * @param productId
     * @param count
     * @return
     */
    AjaxResult decrease(Long productId, Integer count);
}

Interface implementation layer

package cn.tellsea.service.impl;

import cn.tellsea.entity.AjaxResult;
import cn.tellsea.entity.BizStorage;
import cn.tellsea.mapper.BizStorageMapper;
import cn.tellsea.service.IBizStorageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * <p>
 * Inventory table service implementation class
 * </p>
 *
 * @author Tellsea
 * @since 2021-12-31
 */
@Slf4j
@Service
public class BizStorageServiceImpl extends ServiceImpl<BizStorageMapper, BizStorage> implements IBizStorageService {

    @Override
    public AjaxResult decrease(Long productId, Integer count) {
        log.info("------->Start of inventory deduction");
        BizStorage storage = baseMapper.selectById(productId);
        storage.setUsed(storage.getUsed() + count);
        storage.setResidue(storage.getResidue() - count);
        baseMapper.updateById(storage);
        log.info("------->End of inventory deduction");
        return AjaxResult.success("Inventory deduction succeeded");
    }
}

Add annotation to startup class

@EnableDiscoveryClient
@EnableFeignClients
@MapperScan("cn.tellsea.mapper")

6. Test order business

Business requirements: place order - > reduce inventory - > deduct balance - > change order status

(1) Check service startup results

Start three services

Check the service registration of Nacos

visit

http://localhost:8008/bizOrder/createOrder?userId=1&productId=1&count=10&money=100

7. Common error reporting

(1)endpoint format should like ip:port

An error was found when starting the service

2021-03-02 16:22:09.693 ERROR 8384 --- [           main] i.s.c.r.netty.NettyClientChannelManager  : Failed to get available servers: endpoint format should like ip:port

java.lang.IllegalArgumentException: endpoint format should like ip:port
	at io.seata.discovery.registry.FileRegistryServiceImpl.lookup(FileRegistryServiceImpl.java:95) ~[seata-all-1.3.0.jar:1.3.0]
	at io.seata.core.rpc.netty.NettyClientChannelManager.getAvailServerList(NettyClientChannelManager.java:217) ~[seata-all-1.3.0.jar:1.3.0]
	at io.seata.core.rpc.netty.NettyClientChannelManager.reconnect(NettyClientChannelManager.java:162) ~[seata-all-1.3.0.jar:1.3.0]
	at io.seata.core.rpc.netty.RmNettyRemotingClient.registerResource(RmNettyRemotingClient.java:181) [seata-all-1.3.0.jar:1.3.0]
	at io.seata.rm.AbstractResourceManager.registerResource(AbstractResourceManager.java:121) [seata-all-1.3.0.jar:1.3.0]
	at io.seata.rm.datasource.DataSourceManager.registerResource(DataSourceManager.java:146) [seata-all-1.3.0.jar:1.3.0]
	at io.seata.rm.DefaultResourceManager.registerResource(DefaultResourceManager.java:114) [seata-all-1.3.0.jar:1.3.0]

The seata used in this article depends on spring cloud alibaba seata, so the configuration information should be under alibaba

  • tellsea_tx_group: user defined group name, which is the same as vgroupMapping Corresponding to the name after the point
  • Different from the seata version, vgroupMapping may be vgroup mapping, which can be seen directly from the source code
Wrong version
spring:
  cloud:
	# Seata configuration
	seata:
	  tx-service-group: tellsea_tx_group
        
Correct version
spring:
  cloud:
    alibaba:
      # Seata configuration
      seata:
        tx-service-group: tellsea_tx_group

WeChat official account

Topics: Java Distribution Spring Cloud