使用shardingsphere多库分表的,springboot2.6.13,shardingsphere5.2.1,mybatis-plus3.4.3.4、seata1.6.1集成整合

近期尝试进行数据分片,并结合seata,遇到了一堆问题,现将一些内容成果记录如下。
使用的是springboot2.6.13,shardingsphere5.2.1,mybatis使用3.4.3.4,nacos2.0.4,seata使用1.6.1,同时nacos及seata使用docker部署。

1、docker中中间件安装
1.1 nacos安装

docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nacos/nacos-server:v2.0.4
docker tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nacos/nacos-server:v2.0.4  docker.io/nacos/nacos-server:v2.0.4

运行nacos

docker run --restart=always -e MODE=standalone -p 8848:8848 -p 9848:9848 -p 9849:9849 --name nacos -d nacos/nacos-server:v2.0.4

1.2 seata安装

docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/seataio/seata-server:1.6.1
docker tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/seataio/seata-server:1.6.1  docker.io/seataio/seata-server:1.6.1

复制配置文件,先运行一个临时的:

docker run -d --name seata-server -p 8091:8091 -p 7091:7091 seataio/seata-server:1.6.1

创建并复制配置文件

mkdir /myweb/seata-server
docker cp seata-server:/seata-server/resources /myweb/seata-server/resources

删除多余的docker

docker rm -f seata-server

重新运行:

docker run -d --name seata-server -p 8091:8091 -p 7091:7091 \
   -v /myweb/seata-server/resources:/seata-server/resources \
   -e SEATA_CONFIG_NAME=file:/seata-server/resources/registry \
   -e SEATA_IP=192.168.15.10 \
   -e SEATA_PORT=8091 \
   -e SEATA_CONFIG_TYPE=nacos \
   -e SEATA_CONFIG_NACOS_SERVER_ADDR=192.168.15.10:8848 \
   -e SEATA_CONFIG_NACOS_GROUP=SEATA_GROUP \
   -e SEATA_REGISTRY_TYPE=nacos \
   -e SEATA_REGISTRY_NACOS_APPLICATION=seata-server \
   -e SEATA_REGISTRY_NACOS_SERVER_ADDR=192.168.15.10:8848 \
   -e SEATA_REGISTRY_NACOS_GROUP=SEATA_GROUP \
   -e SEATA_STORE_MODE=file \
   seataio/seata-server:1.6.1

nacos增加一个配置:
ID:seataServer.properties
group: SEATA_GROUP
格式:Properties
内容:

store.mode=file
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionTimeout=3600000
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
service.vgroupMapping.default-tx-group=default
service.default.grouplist=192.168.15.10:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread

2、父工程的配置
pom.xml

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.rainpet</groupId>
  <artifactId>springcloud03</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>Archetype - springcloud03</name>
  <url>http://maven.apache.org</url>
  <modules>
    <module>nacos01</module>
    <module>nacos02</module>
    <module>nacos-config01</module>
    <module>seata-order</module>
    <module>seata-order-sharding</module>
    <module>commons</module>
    <module>seata-inventory</module>
  </modules>

  <packaging>pom</packaging>

  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>2.6.13</spring-boot.version>
    <log4j.version>1.2.17</log4j.version>
    <junit.version>4.12</junit.version>
    <spring-cloud.version>2021.0.5</spring-cloud.version>
    <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
    <mysql.version>8.0.29</mysql.version>
    <druid.version>1.2.23</druid.version>
    <mybatis.spring.boot.version>3.5.1</mybatis.spring.boot.version>
    <mybatis-plus.spring.boot.version>3.4.3.4</mybatis-plus.spring.boot.version>
    <lombok.version>1.18.22</lombok.version>
    <jjwt.version>0.9.1</jjwt.version>
    <fastjson.version>2.0.53</fastjson.version>
    <nacos.version>2.0.4</nacos.version>
    <seata.version>1.6.1</seata.version>
    <shardingsphere.version>5.2.1</shardingsphere.version>
    <spring-pagehelper.version>1.4.6</spring-pagehelper.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>${spring-boot.version}</version>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
    <!--type:pom scope:import将上级依赖传递到子模块-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>${spring-boot.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <version>${spring-boot.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>${spring-boot.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-dependencies</artifactId>
      <version>${spring-cloud-alibaba.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-security</artifactId>
      <version>2.2.5.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-oauth2</artifactId>
      <version>2.2.5.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-dubbo</artifactId>
      <version>0.9.0.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>${mybatis-plus.spring.boot.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt</artifactId>
      <version>${jjwt.version}</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba.fastjson2</groupId>
      <artifactId>fastjson2</artifactId>
      <version>${fastjson.version}</version>
    </dependency>
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
      </dependency>
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
      </dependency>
      <dependency>
        <groupId>io.seata</groupId>
        <artifactId>seata-spring-boot-starter</artifactId>
        <version>${seata.version}</version>
      </dependency>
      <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
        <version>${shardingsphere.version}</version>
      </dependency>
      <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>${jjwt.version}</version>
      </dependency>

    </dependencies>
  </dependencyManagement>
</project>

3、子工程的pom.xml

<?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.rainpet</groupId>
        <artifactId>springcloud03</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>seata-order-sharding</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.rainpet</groupId>
            <artifactId>commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-runtime</artifactId>
            <version>4.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>${shardingsphere.version}</version>
        </dependency>
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.33</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>${spring-pagehelper.version}</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>org.rainpet.AppMain8010</mainClass>
                    <!--                    <skip>true</skip>-->
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

4、application.yml

server:
  port: 8010

spring:
    profiles:
        active: local

mybatis-plus:
  mapper-locations: classpath:/mapper/*.xml
  type-aliases-package: org.rainpet.entity
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    cache-enabled: true
  global-config:
    db-config:
      id-type: auto
    banner: false

logging:
  level:
#    io.seata: DEBUG # 开启Seata DEBUG日志
    org.apache.shardingsphere: info # 开启ShardingSphere DEBUG日志

5、application-local.yml

spring:
  main:
    allow-bean-definition-overriding: true # 允许覆盖Bean定义
  application:
    name: seata-order
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.15.10:8848
  shardingsphere:
    datasource:
      names: ds0,ds1
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/mall?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8
        username: hau
        password: 123123
#        data-source-proxy: true
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/mall2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8
        username: hau
        password: 123123
#        data-source-proxy: true
    rules:
      sharding:
        undo_log:
          actual-data-nodes: ds0.undo_log
        tables:
          t_order: #需要分表的物理表名
            actual-data-nodes: ds$->{0..1}.t_order
            database-strategy:
              standard:
                sharding-column: id
                sharding-algorithm-name: database-inline
#            key-generate-strategy:
#              column: id
#              key-generator-name: snowflake
        sharding-algorithms:
          database-inline:
            type: INLINE
            props:
              algorithm-expression: ds$->{id % 2}
    props:
      sql.show: true
      sql-simple: true  # 关闭ShardingSphere的SQL解析
      xa-transaction-manager-type: Seata

seata:
  enabled: true
  enable-auto-data-source-proxy: true
  use-jdk-proxy: true                   # 使用JDK代理避免CGLIB冲突
  data-source-proxy-mode: AT # 数据源代理模式,AT模式是默认的事务模式,支持XA和TCC等事务模式
  mode: AT # 事务模式,AT是默认的事务模式
  application-id: ${spring.application.name}
  tx-service-group: default # 事务组名,默认是default,此处要与seata-server配置 nacos中seataServer.properties的tx-service-group一致
  service:
    vgroup-mapping:
      default: default  #第一个default 与tx-service-group=内容一致
#    disable-global-transaction: false
    grouplist:
      default: 192.168.15.10:8091
  client:
    #    conf: classpath:seata.conf
    undo:
      data-source-proxy-mode: AT  #AT模式下,undo_log表的分库分表策略
    rm:
      report-success-enable: true
  registry:
    type: nacos
    nacos:
      server-addr: 192.168.15.10:8848
#      app-name: ${spring.application.name}
      group: SEATA_GROUP
#      namespace: 512505d7-f5c7-4d05-a5c5-c0c0d0e0f0a0
      username: nacos
      password: nacos
      cluster: default
      application: seata-server #此处其实是seata-server配置的应用名,是和seata-server配置的application一致
  config:
    type: nacos
    nacos:
      server-addr: 192.168.15.10:8848
      group: SEATA_GROUP
#      namespace: 512505d7-f5c7-4d05-a5c5-c0c0d0e0f0a0
      username: nacos
      password: nacos
      data-id: seataServer.properties

#  saga:
#    enabled: true # 启用Saga模式 还有如AT模式等,默认为AT模式

6、主程序,seataOrderSharding8010.java

package org.rainpet;

import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import lombok.experimental.var;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@SpringBootApplication
@MapperScan("org.rainpet.mapper")
@EnableDiscoveryClient
//@EnableAutoDataSourceProxy
@EnableFeignClients
@EnableTransactionManagement
public class seataOrderSharding8010 {
    @Autowired
    private DataSource dataSource;

    public static void main(String[] args) {
        var ctx = SpringApplication.run(seataOrderSharding8010.class, args);
        DataSource ds = ctx.getBean(DataSource.class);
        System.out.println("当前DataSource类型: " + ds.getClass().getName());
    }
//    @Bean
//    public GlobalTransactionScanner globalTransactionScanner() {
//        return new GlobalTransactionScanner("seata-order", "default-tx-group");
//    }
}

7、OrderController.java

package org.rainpet.controller;

import org.rainpet.entity.Order;
import org.rainpet.mapper.OrderMapper;
import org.rainpet.service.OrderService;
import org.rainpet.vo.ResponseSet;
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;

import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderMapper mapper;

    @Autowired
    private OrderService service;

    @GetMapping("/list")
    public List<Order> getOrderList(){
        return mapper.selectList(null);
    }

    @GetMapping("/add")
    public ResponseSet addOrder(){
        service.addOrder();
        return new ResponseSet("200", "添加成功",null);
    }
    @GetMapping("/add2")
    public ResponseSet addOrder2(){
        service.addOrderWithException();
        return new ResponseSet("200", "添加成功",null);
    }
}

8、OrderService.java

package org.rainpet.service;

public interface OrderService {
    public void addOrder();
    public void addOrderWithException();
}

9、InventoryService.java

package org.rainpet.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "seata-inventory")
public interface InventoryService {
    @GetMapping("/inv/add")
    public String addInventory();
}

10、OrderServiceImpl.yml

package org.rainpet.service.impl;

import io.seata.spring.annotation.GlobalTransactional;
import org.rainpet.entity.Order;
import org.rainpet.mapper.OrderMapper;
import org.rainpet.service.InventoryService;
import org.rainpet.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private OrderMapper mapper;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void addOrder() {
        Order order = new Order();
        order.setOrderTime(LocalDateTime.now());
        order.setOrderAddress("上海");
        order.setOrderType(1);

        mapper.insert( order);// 插入订单数据
        inventoryService.addInventory();// 调用库存服务
//        if(true)throw new RuntimeException("测试异常回滚");
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public void addOrderWithException() {
        Order order = new Order();
        order.setOrderTime(LocalDateTime.now());
        order.setOrderAddress("北京");
        order.setOrderType(2);

        mapper.insert( order);// 插入订单数据
        inventoryService.addInventory();// 调用库存服务
        if(true)throw new RuntimeException("测试异常回滚");
    }
}

11、Inventory.java

package org.rainpet.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.math.BigDecimal;

@Data
@TableName("t_inventory")
public class Inventory {
    @TableId(value = "inv_id", type = IdType.AUTO)
    private Integer invId;
    private String invName;
    private BigDecimal invQty;
}

12、Order.java

package org.rainpet.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@TableName("t_order")
public class Order {
    @TableId(type = IdType.ASSIGN_ID) // 使用雪花算法生成ID
    private Long id;
//    private Integer orderId = 0;
    private LocalDateTime orderTime;
    private String orderAddress;
    private Integer orderType;
}

13、InventoryMapper.java

package org.rainpet.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.rainpet.entity.Inventory;
import org.springframework.stereotype.Repository;

//@Repository
public interface InventoryMapper extends BaseMapper<Inventory> {
}

14、OrderMapper.java

package org.rainpet.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.rainpet.entity.Order;

//@Mapper
public interface OrderMapper extends BaseMapper<Order> {
//    public void save(Order order);
}

15、ResponseSet.java

package org.rainpet.vo;

import lombok.Data;

@Data
public class ResponseSet {
    private String code;
    private String msg;
    private Object data;
    private String requestId;
    public ResponseSet(String code, String msg, Object data, String requestId) {
        this.code = code;
        this.msg = msg;
        this.data = data;
        this.requestId = requestId;
    }

    public ResponseSet(String code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

}

还有一点,之前当有异常抛出时,一直没有回滚,后来发现与springboot的版本有关系,我使用springboot2.6.13就可以,但是springboot2.6.3不行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lwprain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值