史上最全Spring的@Transactional不生效的12大场景

news2024/11/13 8:03:52

一、事务不生效

1、访问权限的问题

在Spring框架中,AbstractFallbackTransactionAttributeSource是用于确定一个给定的方法是否应该被事务管理的一个抽象类。它的computeTransactionAttribute方法用于计算并返回一个方法的TransactionAttribute。computeTransactionAttribute方法中有个判断如果目标不是public,则TransactionAttribute会返回null,即不支持事务。

@Nullable
	protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		// Don't allow no-public methods as required.
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

		// The method may be on an interface, but we need attributes from the target class.
		// If the target class is null, the method will be unchanged.
		Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

		// First try is the method in the target class.
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

		// Second try is the transaction attribute on the target class.
		txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}

		if (specificMethod != method) {
			// Fallback is to look at the original method.
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) {
				return txAttr;
			}
			// Last fallback is the class of the original method.
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

		return null;
	}

当然,这种行为是可以根据需要进行调整的。如果您确实需要为非公共方法提供事务支持,可以通过自定义TransactionAttributeSource实现来覆盖这种默认行为。

2、方法被final修饰

Java中的final关键字用来声明一个不可变的成员变量或方法。当一个方法被声明为final时,意味着这个方法不能被子类重写。然而,final方法与Spring的事务管理之间的关系并不是直接相关的,因为事务管理是在运行时通过代理机制实现的,而不是通过方法的可重写性来控制的。

在Spring框架中,事务管理通常是通过AOP(面向切面编程)实现的。对于一个带有事务注解(如@Transactional)的方法,Spring AOP会在运行时动态创建一个代理对象来调用该方法,并在这个过程中插入必要的事务管理逻辑。具体来说,Spring使用了两种主要的代理类型:

  • JDK动态代理:适用于实现了接口的类。
  • CGLIB代理:适用于没有实现任何接口的类,或者方法级的拦截。

对于带有@Transactional注解的方法,Spring会尝试通过这些代理来执行该方法,并在其前后添加事务管理代码。但是,当方法被声明为final时,情况会有所不同:

  1. JDK动态代理final方法并不会影响JDK动态代理的行为,因为JDK动态代理并不修改目标类本身,而是创建一个新的代理类来实现相同接口。所以,在使用JDK动态代理的情况下,即使方法被声明为final,事务管理仍然能够正常工作。
  2. CGLIB代理:CGLIB代理通过字节码增强的方式生成子类,然后重写目标类的方法以实现方法级别的拦截。这意味着,如果目标类的方法被声明为final,CGLIB就无法重写这个方法,因此也就无法为其添加事务管理的逻辑。在这种情况下,事务管理将会失效。

总结来说,如果类使用了CGLIB代理,并且该类中的方法被声明为final,那么这些方法上的事务管理将不会生效。为了避免这种情况,可以选择使用JDK动态代理,但这要求类必须实现至少一个接口。另一种解决方法是移除final关键字,这样无论使用哪种代理方式,事务管理都可以正常工作。

如果需要确保final方法也能支持事务管理,并且类没有实现任何接口,那么可能需要考虑其他替代方案,比如更改类的设计使其不再使用final方法,或者使用基于XML的配置来显式指定代理类型。

3、内部调用

在Spring框架中,内部方法调用(即一个类中的方法调用该类内的另一个方法)通常不会触发事务边界。这是因为Spring的事务管理是通过AOP(面向切面编程)代理实现的,而代理只能处理对类的外部调用,而不是类内部的方法调用。

当一个类中的方法被标记为@Transactional时,Spring会为这个类创建一个代理。当外部代码调用该类的一个方法时,实际上是调用了代理对象上的方法,这样就可以在调用前后添加事务管理逻辑。但是,如果一个方法内部调用另一个方法,这种调用发生在同一个实例内部,因此不会经过代理层,也就不会触发事务管理。

例如,假设有一个类Service,其中包含两个方法publicMethodprivateMethod,并且这两个方法都被标记为@Transactional

@Service
public class Service {

    @Transactional
    public void publicMethod() {
        privateMethod();
    }

    @Transactional
    private void privateMethod() {
        // ...
    }
}

在这种情况下,只有publicMethod的外部调用会被代理并受到事务管理。privateMethod的调用由于发生在类内部,不会触发事务边界。这意味着privateMethod实际上不会按照预期那样被事务管理。

为了确保所有方法都受到事务管理,可以采取以下几种策略之一:

  1. 使用@Transactional注解类级别: 如果所有方法都需要事务管理,可以将@Transactional注解放在类级别上,这样所有公开的方法都会自动被事务管理。
  2. 自我调用模式: 使用代理对象来自我调用方法,以确保方法调用会经过代理,从而触发事务管理。例如,您可以将方法改为如下形式:
@Service
public class Service {

    @Autowired
    private Service self;

    @Transactional
    public void publicMethod() {
        self.privateMethod();
    }

    @Transactional
    private void privateMethod() {
        // ...
    }
}
  1. 使用@Transactional(propagation = Propagation.REQUIRES_NEW)

如果希望在内部方法调用时也开启新的事务,可以使用REQUIRES_NEW传播行为。这将确保每个方法都在自己的事务中运行,即使是从另一个事务方法内部调用也是如此。但请注意,这种方式可能会导致性能问题,因为每个方法都会开始一个新事务。

@Service
public class Service {

    @Transactional
    public void publicMethod() {
        privateMethod();
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    private void privateMethod() {
        // ...
    }
}

4、未被spring管理

即使用spring事务的前提是:对象要被spring管理,需要创建bean实例(低级错误一般不会发生)

5、多线程调用

Spring的事务管理是基于线程本地变量(ThreadLocal)来实现的。具体来说,Spring使用ThreadLocal来存储当前线程的事务上下文信息。当一个线程开始一个新的事务时,该事务的信息会被绑定到当前线程的ThreadLocal变量中。当方法完成或异常发生时,事务会被提交或回滚,然后从ThreadLocal中清除。

在多线程环境下,有几个关键点需要注意:

  1. 独立线程的事务隔离
    • 每个线程都有其自己的ThreadLocal副本,这意味着不同线程之间的事务上下文是相互隔离的。这意味着如果一个线程启动了一个事务,而另一个线程试图访问同一资源,它将看不到前一个线程中的事务状态,除非显式地通过某种机制共享事务上下文。
  2. 共享资源的事务管理
    • 当多个线程试图访问由Spring管理的同一资源时,如果没有适当的同步机制,可能会出现并发问题。例如,如果一个线程正在执行一个事务中的操作,而另一个线程同时尝试修改相同的资源,那么第二个线程的操作可能会干扰第一个线程的事务。
  3. 显式事务管理
    • 对于需要跨线程共享事务上下文的情况,通常需要显式地管理事务,例如通过使用TransactionTemplatePlatformTransactionManager API手动管理事务。这样可以在需要的时候显式地开始、提交或回滚事务。
  4. 线程池中的事务管理
    • 如果您使用的是线程池,那么线程池中的线程会复用。这意味着如果一个线程在一个事务中结束并被归还到线程池中,然后被重新分配到一个新的任务,它可能会携带旧的事务上下文。为了避免这种情况,可以使用TransactionSynchronizationManager来清理线程本地的事务状态。
  5. 使用@Transactional注解
    • 如果使用@Transactional注解来声明事务边界,那么只要确保线程调用符合Spring AOP的代理机制,事务管理通常会按预期工作。但是,如果多个线程并发地调用同一个带有@Transactional注解的方法,那么每个线程都会有自己的事务实例。
  6. 事务传播行为
    • 对于在多线程环境中使用@Transactional的方法,了解事务传播行为非常重要。例如,如果您使用PROPAGATION_REQUIRES_NEW,那么即使在一个线程内,内部方法调用也会创建一个新的事务实例。

总结

  • 多线程环境下的事务管理需要特别注意,特别是当涉及到共享资源时。
  • 如果希望在多线程环境中保持事务的一致性,通常需要显式地管理事务,或者确保事务传播行为符合需求。
  • 使用@Transactional注解时,每个线程会有自己的事务实例,除非显式地配置事务传播行为来改变这一点。

要确保多线程环境中事务的正确管理,可能需要考虑使用更高级别的事务管理API,例如TransactionTemplatePlatformTransactionManager,并在必要时使用同步机制来确保事务的正确性。

6、表不支持事务

众所周知,在mysql5前,默认的数据库引擎是myisam

它的好处:索引文件和数据文件是分开储存的,对于查多写少的表达操作,性能比innodb更好

有些老项目中,可能还在用它。

在创建表的时候,只需要把ENGINE参数设置为MyISAM即可

myisam好用就是有一个致命的缺点:不支持事务

如果单表操作还好,但是如需跨表操作,由于不支持事务数据极有可能出现数据不完整的情况。

7、未开启事务

在spring boot(现在spring boot是默认开启的)未出来之前,spring开启事务是需要配置的,如果未配置的话就默认不开启。

以下是spring的xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 定义事务规则 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>

    <!-- 关联事务规则与切点 -->
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.example.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>
</beans>

二、事务不回滚

1、错误的传播特性

Spring提供了七种不同的传播行为,每种都有不同的用途。以下是这些传播行为的概述:

  1. PROPAGATION_REQUIRED:
    • 这是默认的传播行为。
    • 如果当前存在事务,则加入该事务。
    • 如果当前不存在事务,则创建一个新的事务。
  2. PROPAGATION_SUPPORTS:
    • 如果当前存在事务,则加入该事务。
    • 如果当前不存在事务,则以非事务方式执行。
  3. PROPAGATION_MANDATORY:
    • 如果当前存在事务,则加入该事务。
    • 如果当前不存在事务,则抛出TransactionRequiredException
  4. PROPAGATION_REQUIRES_NEW:
    • 创建一个新的事务。
    • 如果当前存在事务,则挂起该事务。
    • 新事务完成后,恢复之前被挂起的事务(如果有的话)。
  5. PROPAGATION_NOT_SUPPORTED:
    • 以非事务方式执行。
    • 如果当前存在事务,则挂起该事务。
  6. PROPAGATION_NEVER:
    • 以非事务方式执行。
    • 如果当前存在事务,则抛出IllegalTransactionStateException
  7. PROPAGATION_NESTED:
    • 如果当前存在事务,则执行一个嵌套事务。
    • 如果当前不存在事务,则表现得像PROPAGATION_REQUIRED

目前只有三种传播特性才会创建新事务:

PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED

2、自己吞了异常

事务不回滚,最常见的问题是:开发者在代码中手动try…catch了异常。

因为开发者自己捕获了异常,又没有手动抛出

@Service
public class ExampleService {

    @Transactional
    public void updateData() {
        try {
            someMethodThatMightThrowException();
        } catch (Exception e) {
            log.error("An error occurred", e);
            // 这里没有再次抛出异常
        }
    }

    private void someMethodThatMightThrowException() {
        // 这里可能会抛出异常
        throw new RuntimeException("An error occurred");
    }
}

解决方案

为了避免这种情况,可以采取以下几种措施:

再次抛出异常

  • catch块中再次抛出异常,这样事务管理器会捕捉到异常并回滚事务。
@Transactional
public void updateData() {
    try {
        someMethodThatMightThrowException();
    } catch (Exception e) {
        log.error("An error occurred", e);
        throw e;  // 再次抛出异常
    }
}

使用rollbackFor属性

  • 如果希望捕获特定类型的异常而不回滚事务,可以使用@Transactional注解中的rollbackFor属性来指定哪些类型的异常会导致事务回滚。
@Transactional(rollbackFor = RuntimeException.class)
public void updateData() {
    try {
        someMethodThatMightThrowException();
    } catch (Exception e) {
        log.error("An error occurred", e);
        if (e instanceof RuntimeException) {
            throw e;  // 再次抛出运行时异常
        }
    }
}

使用noRollbackFor属性

  • 如果希望某些类型的异常不会导致事务回滚,可以使用noRollbackFor属性。
@Transactional(noRollbackFor = IOException.class)
public void updateData() {
    try {
        someMethodThatMightThrowException();
    } catch (IOException e) {
        log.error("An I/O error occurred", e);
        // 不再抛出异常
    } catch (Exception e) {
        log.error("An error occurred", e);
        throw e;  // 再次抛出其他类型的异常
    }
}

使用@Transactional注解的readOnly属性

  • 如果方法是只读的,即不会修改数据库状态,可以将readOnly属性设置为true。这样,即使方法抛出异常,事务也不会回滚。
@Transactional(readOnly = true)
public void updateData() {
    try {
        someMethodThatMightThrowException();
    } catch (Exception e) {
        log.error("An error occurred", e);
        throw e;  // 再次抛出异常
    }
}

3、手动抛了别的异常

因为spring事务,默认情况下只会回滚RuntimeException(运行时异常)和Error(错误),对于普通的Exception(非运行时异常),它不会回滚。

以下设置都会回滚

@Service
public class ExampleService {

    @Transactional(rollbackFor = Exception.class)
    public void updateData() {
        try {
            someMethodThatMightThrowException();
        } catch (Exception e) {
            log.error("An error occurred", e);
            throw e;  // 再次抛出异常
        }
    }

    private void someMethodThatMightThrowException() throws Exception {
        // 这里可能会抛出异常
        throw new Exception("An error occurred");
    }
}

4、自定义了回滚异常

这个一般是使用rollbackFor参数来设置的,建议rollbackFor = Exception.class不会出现问题

5、嵌套事务回滚多了

在Spring中,嵌套事务可以通过PROPAGATION_NESTED传播行为来实现。当一个事务方法调用另一个事务方法,并且后者使用PROPAGATION_NESTED时,将创建一个嵌套事务。如果嵌套事务回滚,这通常意味着:

  1. 嵌套事务回滚
    • 如果嵌套事务中发生了异常并导致回滚,那么嵌套事务所做的更改将被撤销。
    • 如果嵌套事务回滚,它不会自动导致父事务回滚,除非嵌套事务抛出了RollbackExceptionRuntimeException等未被捕获的异常。
  2. 父事务状态
    • 父事务的状态不受嵌套事务回滚的直接影响,除非嵌套事务抛出的异常导致父事务也回滚。
    • 如果嵌套事务回滚,但父事务中的其他部分仍然成功执行,那么父事务将继续进行。

假设有以下代码:

@Service
public class ExampleService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void outerMethod() {
        innerMethod();
    }

    @Transactional(propagation = Propagation.NESTED)
    public void innerMethod() {
        try {
            someMethodThatMightThrowException();
        } catch (Exception e) {
            log.error("An error occurred in nested transaction", e);
            // 如果需要回滚父事务,可以抛出 RollbackException 或 RuntimeException
            throw new RollbackException("Nested transaction failed");
        }
    }

    private void someMethodThatMightThrowException() {
        // 这里可能会抛出异常
        throw new Exception("An error occurred");
    }
}

在这个例子中,outerMethod 使用 PROPAGATION_REQUIRED,而 innerMethod 使用 PROPAGATION_NESTED。如果 innerMethod 抛出异常,那么嵌套事务将回滚,但由于我们抛出了 RollbackException,这将导致父事务 outerMethod 也回滚。

解决方案

  1. 显式控制回滚

    • 如果希望嵌套事务的回滚导致父事务回滚,可以在嵌套事务中抛出 RollbackExceptionRuntimeException
    • 如果不希望嵌套事务的回滚影响父事务,可以捕获异常并处理,但不要抛出 RollbackExceptionRuntimeException
  2. 使用@Transactional注解的rollbackFor属性

    • 如果希望嵌套事务中的特定异常导致父事务回滚,可以使用 @Transactional(rollbackFor = YourException.class) 来指定这些异常。
  3. 其实还可以在子事务中通过try…catch吃掉异常,这样也可以使父事务不受影响
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1957483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SD NAND存储卡:小尺寸下的大容量存储

SD NAND是一种基于NAND闪存技术的存储设备&#xff0c;采用SD卡形式&#xff0c;具备高存储容量、高速度和高可靠性的特点&#xff0c;广泛应用于嵌入式系统和消费电子产品中。 在如今数据驱动的世界&#xff0c;存储技术的发展至关重要。MK米客方德作为存储芯片行业的领先者&…

C++(week14): C++提高:(一)面向对象设计:设计原则、设计模式

文章目录 一、面向对象设计的概念4.统一建模语言&#xff1a;UML语言StartUML 二、类与类之间的关系0.总结(1)类与类的五种关系(2)区别(3)面向对象 vs 基于对象 1.继承 (泛化耦合)2.组合 (Composition)3.聚合 (Aggregation)4.关联(1)双向关联(2)单向关联 5.依赖 (Dependency) 三…

JNDI注入-RMI和Reference

参考博客&#xff1a; JNDI注入与动态类加载 JNDI Java命名和接口目录为用Java编程语言编写的应用程序提供命名和目录功能。 可以通过一种通用方式访问各种服务&#xff0c;类似通过名字查找对象的功能&#xff0c;和RMI有点类似。 原生JNDI支持RMI&#xff0c;LDAP&#…

2024最新前端学习路线指南!

2024最新前端学习路线指南&#xff01; 如果你正在寻找一份全面的前端学习路线图&#xff0c;那么这份精心打造的学习大纲恰好符合您的需求。无论您是新手还是经验丰富的开发者&#xff0c;这份路线图都能够帮助您系统地掌握前端开发的关键知识点&#xff0c;并在实践中不断提…

实验2-3-7 阶梯电价

//实验2-3-7 阶梯电价 /*为了提倡居民节约用电&#xff0c;某省电力公司执行“阶梯电价”&#xff0c; 安装一户一表的居民用户电价分为两个“阶梯”&#xff1a; 月用电量50千瓦时&#xff08;含50千瓦时&#xff09;以内的&#xff0c;电价为0.53元/千瓦时&#xff1b; 超过5…

java实现加水印功能

1-Word加水印 实现原理&#xff1a; ● 通过页眉页脚生成文字水印或图片水印&#xff0c;然后设置页眉页脚的高度以及旋转角度来设置水印。 源代码&#xff1a; 1、引入pom依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml…

家具购物小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;家具分类管理&#xff0c;家具新品管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;家具新品&#xff0c;家具公告&#xff0…

给配置环境变量的小白们的一个tips

告诉什么也不懂的计算机小白包括我&#xff0c;配置环境变量的时候&#xff0c;系统变量配置好之后&#xff0c;path变量一定要去users里加&#xff0c;不要在系统变量里加&#xff0c;不然查版本号的时候你就会像我一样在命令行里傻傻的 你加到系统变量的path后&#xff0c;在…

Linux网络——深入理解传入层协议TCP

目录 一、前导知识 1.1 TCP协议段格式 1.2 TCP全双工本质 二、三次握手 2.1 标记位 2.2 三次握手 2.3 捎带应答 2.4 标记位 RST 三、四次挥手 3.1 标记位 FIN 四、确认应答(ACK)机制 五、超时重传机制 六 TCP 流量控制 6.1 16位窗口大小 6.2 标记位 PSH 6.3 标记…

昇思25天学习打卡营第10天|xiaoyushao

从今天开始做一些实践应用&#xff0c;今天分享的是FCN图像语义分割。 全卷积网络&#xff08;Fully Convolutional Networks&#xff0c;FCN&#xff09;是UC Berkeley的Jonathan Long等人于2015年在Fully Convolutional Networks for Semantic Segmentation一文中提出的用于图…

值得买科技与MiniMax达成官方合作伙伴关系,共建融合生态

7月29日&#xff0c;值得买科技与大模型公司MiniMax宣布达成官方合作伙伴关系。 MiniMax旗下大模型产品海螺AI现已接入值得买“消费大模型增强工具集”&#xff0c;基于海螺AI比价策略&#xff0c;用户可通过海螺AI“悬浮球”功能实现快速比价及跳转购买。 此次合作也标志着值…

2023河南萌新联赛第(二)场 南阳理工学院

A. 国际旅行Ⅰ 题目&#xff1a; 思路&#xff1a; 因为题意上每个国家可以相互到达&#xff0c;所以只需要排序&#xff0c;输出第k小的值就可以了。 AC代码&#xff1a; #include<bits/stdc.h> #define int long long #define IOS ios::sync_with_stdio(0);cin.tie…

springboot短视频推荐系统-计算机毕业设计源码21503

摘 要 本论文基于协同过滤算法&#xff0c;旨在设计并实现一种基于SpringBoot框架的短视频推荐系统。该系统主要分为平台用户和管理员两类角色&#xff0c;用户可以注册、登录、浏览短视频内容&#xff0c;并根据个人兴趣收藏喜爱的视频。管理员则可以管理系统数据、用户和内容…

3.1.数据增广

数据增广 ​ 以图片为例&#xff0c;在不同的灯光&#xff0c;色温&#xff0c;以及灯光反射的影响下&#xff0c;对识别可能会造成很大影响。这时候我们希望样本有更多的多样性&#xff0c;则可以在语言里面加入各种不同的背景噪音&#xff0c;或者改变图片的颜色和形状 1.常…

【2024蓝桥杯/C++/B组/进制】

题目 代码 #include <bits/stdc.h> using namespace std;// 定义一个字符串 str&#xff0c;其内容为 "8100178706957568" string str "8100178706957568";// 函数 check 用于检查传入的字符串是否全部由数字组成 bool check(const string& st…

Java(二十七)---二叉搜索树以及Map和Set

文章目录 前言1.二叉搜索树1.1.概念1.2.操作--- 插入1.3.操作---搜索1.4.操作---删除1.6.性能分析1.7 和 java 类集的关系 2.搜索2.1.概念和场景2.2.模型 3.Map的使用3.1.关于Map的说明3.2.Map.Entry<K,V>的说明3.3.Map中常用的方法3.4.TreeMap的使用案例 4.Set的使用4.1…

探索 Milvus 存储系统:如何评估和优化 Milvus 存储性能

欢迎来到探索 Milvus 系列。Milvus 是一款支持水平扩展和具备出色性能的开源向量数据库。Milvus 的核心是其强大的存储系统&#xff0c;是数据持久化和存储的关键基础。该系统包括几个关键组成部分&#xff1a;元数据存储&#xff08;meta storage&#xff09;、消息存储&#…

Vs2022+QT+Opencv 一些需要注意的地方

要在vs2022创建QT项目&#xff0c;先要安装一个插件Qt Visual Studio Tools&#xff0c;根据个人经验选择LEGACY Qt Visual Studio Tools好一些&#xff0c;看以下内容之前建议先在vs2022中配置好opencv&#xff0c;配置方式建议以属性表的形式保存在硬盘上。 设置QT路径 打开v…

数学建模--差值算法

目录 插值方法的种类 应用实例 编程实现 算法实现 拉格朗日插值算法 ​编辑 多项式差值算法 样条插值 牛顿插值算法 插值算法在数据预测中的最新应用和案例研究是什么&#xff1f; 如何比较不同插值方法&#xff08;如线性插值、多项式插值&#xff09;在实际工程问…

bjtu数据库课程设计--基于Spring Boot框架的门店点餐系统

一、安装与配置 1 安装与配置 下载IntelliJ IDEA&#xff0c;需要下载安装jdk1.8.0_152&#xff0c;安装tomcat-9.0.88&#xff0c;安装MySQL8.0数据库。安装成功后打开IntelliJ IDEA&#xff0c;使用 Spring Boot 2.6.13框架&#xff0c;服务器URL窗口使用start.aliyun.com&a…