SpringBoot 事务失效及其对应解决办法

简介

本文主要讲述Spring事务会去什么情况下失效及其解决办法

Spring 通过AOP 进行事务控制,如果操作数据库报异常,则会进行回滚;如果没有报异常则会提交事务;但是,如果Spring 事务失效,会导致数据缺失/重复等异常问题。

演示环境 

编译工具:IDEA 社区版本

数据库:MySQL 8

框架:SpringBoot 2.1.0 + MyBatis-plus3.4.3 + lombok等

库表:

-- bill.base_project definitionCREATE TABLE `base_project` (`id` varchar(64) NOT NULL COMMENT '主键',`tid` varchar(64) NOT NULL COMMENT '地区行政编码',`ptid` varchar(64) NOT NULL COMMENT '所属省级行政编码',`project_name` varchar(256) NOT NULL COMMENT '项目名称',`project_address` varchar(512) DEFAULT NULL COMMENT '项目地址',`project_no` varchar(128) NOT NULL COMMENT '项目编号',`developer_entity_name` varchar(218) DEFAULT NULL COMMENT '开发企业名称',`developer_entity_no` varchar(128) DEFAULT NULL COMMENT '开发企业编号',`suery_unit` varchar(128) DEFAULT NULL COMMENT '勘察单位',`design_unit` varchar(128) DEFAULT NULL COMMENT '设计单位',`build_unit` varchar(128) DEFAULT NULL COMMENT '施工单位',`supervisor_unit` varchar(128) DEFAULT NULL COMMENT '监理单位',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

SpringBootCase 父类项目 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><packaging>pom</packaging><modules><module>SpringBoot-MyBatisPlus</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.0.RELEASE</version></parent><groupId>org.example</groupId><artifactId>SpringBootCase</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-properties-migrator</artifactId><scope>runtime</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

SpringBoot-MyBatisPlus 子类项目 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"><parent><artifactId>SpringBootCase</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>SpringBoot-MyBatisPlus</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><mybatisplus-spring-boot-starter.version>3.4.3</mybatisplus-spring-boot-starter.version><mysql-spring-boot-starter.version>8.0.19</mysql-spring-boot-starter.version></properties><dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatisplus-spring-boot-starter.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql-spring-boot-starter.version}</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><executable>true</executable><!--必须为ZIP模式,不指定的话-Dloader.path不生效--><layout>ZIP</layout><!-- 打包的时候排除的jar包--><includes><include><groupId>non-exists</groupId><artifactId>non-exists</artifactId></include></includes></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><!--指定的依赖路径--><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin></plugins></build></project>

资源配置文件:application.yml

server:port: 8080
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.43.10:3306/bill?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&autoReconnect=trueusername: rootpassword: 123456hikari:minimum-idle: 10maximum-pool-size: 20idle-timeout: 500000max-lifetime: 540000connection-timeout: 60000connection-test-query: select 1mybatis-plus:mapper-locations: classpath:mapper/*.xmltype-aliases-package: cn.zzg.mybatisplus.entity

其他相关文件,会在相关代码演示中一一讲解

JDBC 事务原理

我这里简单编写了一份jdbc 事务管理的通用伪代码:

//获取数据库连接
Connection connection = DriverManager.getConnection();
//设置自动提交为false
connection.setAutoCommit(false);
// SQL 操作
.........
//事务提交或回滚
connection.commit()/connection.rollback
//关闭数据库连接
connection.close();

 Spring 事务原理

Spring 通过事务注解@Transactional来控制事务,底层实现是基于切面编程AOP实现的,而Spring中实现AOP机制采用的是动态代理,具体分为JDK动态代理和CGLIB动态代理两种模式。

功能描述:

1.Spring 在bean的初始化过程中,检查方法是否被Transactional注解修饰,如果方法被修饰需要对相应的Bean进行代理,生成代理对象。

2. 在方法调用的时候,会执行切面的逻辑,而这里切面的逻辑中就包含了开启事务、提交事务或者回滚事务等逻辑。

温馨提示:Spring 本身不实现事务,底层还是依赖于数据库的事务。

Spring 事务失效场景

前提Mapper接口和PO对象:

package cn.zzg.mybatisplus.mapper;import cn.zzg.mybatisplus.entity.BaseProjectPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface BaseProjectMapper extends BaseMapper<BaseProjectPO> {
}
package cn.zzg.mybatisplus.entity;import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;@Data
@TableName("base_project")
public class BaseProjectPO extends Model {private String id;private String tid;private String ptid;private String projectName;private String projectAddress;private String projectNo;private String developerEntityName;private String developerEntityNo;private String sueryUnit;private String designUnit;private String buildUnit;private String supervisorUnit;
}
package cn.zzg.mybatisplus.service;import cn.zzg.mybatisplus.entity.BaseProjectPO;
import com.baomidou.mybatisplus.extension.service.IService;import java.io.IOException;public interface IBaseProjectService extends IService<BaseProjectPO> {
}

1.抛出异常

比如事务代码控制如下:

在IBaseProjectService服务接口,新增如下方法定义:

 void insertBaseProject1(BaseProjectPO baseProject) throws IOException;

 在BaseProjectServiceImpl服务实现类中如下实现:

   @Transactional@Overridepublic void insertBaseProject1(BaseProjectPO baseProject) throws IOException {boolean target = this.baseMapper.insert(baseProject) > 0 ? true: false;throw new IOException();}

在Controller调用该方法

   @GetMapping("/insert1")public boolean insert1() throws IOException {BaseProjectPO po = new BaseProjectPO();po.setId("4");po.setTid("4");po.setPtid("4");po.setProjectNo("4");po.setProjectName("4");service.insertBaseProject1(po);return true;}

最终数据库库表截图: 

说明此事务失效。 

造成原因

@Transactional 没有特别指定异常,Spring 只会在遇到运行时异常RuntimeException或者error时进行回滚,而IOException等异常不会影响回滚。

解决办法:

配置rollbackFor属性,常用配置为:@Transactional(rollbackFor = Exception.class)

服务类调整后,事务生效代码片段

   @Transactional(rollbackFor = Exception.class)@Overridepublic void insertBaseProject1(BaseProjectPO baseProject) throws IOException {boolean target = this.baseMapper.insert(baseProject) > 0 ? true: false;throw new IOException();}

2.业务方法捕获异常

在IBaseProjectService服务接口,新增如下方法定义:
 void insertBaseProject2(BaseProjectPO baseProject) ;

在BaseProjectServiceImpl服务实现类中如下实现:

    @Transactional(rollbackFor = Exception.class)@Overridepublic void insertBaseProject2(BaseProjectPO baseProject) {try{this.baseMapper.insert(baseProject);int i = 1/0;}catch (Exception e){e.printStackTrace();}}

在Controller调用该方法

 @GetMapping("/insert1")public boolean insert1() throws IOException {BaseProjectPO po = new BaseProjectPO();po.setId("5");po.setTid("5");po.setPtid("5");po.setProjectNo("5");po.setProjectName("5");service.insertBaseProject2(po);return true;}

最终数据库库表截图: 

 说明此事务失效。 

造成原因:

Spring是否进行回滚是根据你的代码是否抛出异常决定的,所以如果你自己捕获了异常,自己处理并且没有抛出异常会导致Spring 事务失效。

解决办法:

1.配置rollbackFor属性,常用配置为:@Transactional(rollbackFor = Exception.class)。并在try...catch 代码片段中抛出相关异常。

2.使用编写式事务,个人推荐使用。

transactionTemplate.execute

服务类调整后,事务生效代码片段

第一种方法:

    @Transactional(rollbackFor = Exception.class)@Overridepublic void insertBaseProject2(BaseProjectPO baseProject) throws IOException {try{this.baseMapper.insert(baseProject);int i = 1/0;}catch (Exception e){e.printStackTrace();throw new IOException();}}

第二种方法:

    @Overridepublic void insertBaseProject2(BaseProjectPO baseProject) {transactionTemplate.execute(new TransactionCallbackWithoutResult(){@Overrideprotected void doInTransactionWithoutResult(TransactionStatus status) {try {BaseProjectServiceImpl.super.baseMapper.insert(baseProject);int i = 1/0;} catch (Exception e) {status.setRollbackOnly() ;}}});}

温馨提示:记录用户操作日志优化点......

3.同一类中的方法调用

在IBaseProjectService服务接口,新增如下方法定义:

 boolean insertBaseProject(BaseProjectPO baseProject);

在BaseProjectServiceImpl服务实现类中如下实现:

  @Overridepublic boolean insertBaseProject(BaseProjectPO baseProject) {return this.insertTrans(baseProject);}@Transactionalpublic boolean insertTrans(BaseProjectPO baseProject){// 数据库操作boolean target = this.baseMapper.insert(baseProject) > 0 ? true: false;// 模拟异常操作int i = 1/0;return target;}

在Controller调用该方法

@GetMapping("/insert")public boolean insert() {BaseProjectPO po = new BaseProjectPO();po.setId("2");po.setTid("2");po.setPtid("3");po.setProjectNo("2");po.setProjectName("2");return service.insertBaseProject(po);}

最终数据库库表截图: 

 说明此事务失效。

造成原因:

Spring的事务管理功能是通过动态代理实现的,而Spring默认使用JDK动态代理,而JDK动态代理采用接口实现的方式,通过反射调用目标类。简单理解,就是insertBaseProject()方法中调用this.insertTrans(),这里的this是真实对象,所以会直接走insertTrans()的业务逻辑,而不会走切面逻辑,所以事务失败。

Aop 事务伪代码

@Service
class A{@Transactinalmethod b(){...}method a(){    //标记1b();}
}//Spring扫描注解后,创建了另外一个代理类,并为有注解的方法插入一个startTransaction()方法:
class proxy$A{A objectA = new A();method b(){    //标记2startTransaction();objectA.b();}method a(){    //标记3objectA.a();    //由于a()没有注解,所以不会启动transaction,而是直接调用A的实例的a()方法}
}

详细说明:

当我们调用A的bean的a()方法的时候,也是被proxy$A拦截,执行proxy$A.a()(标记3),然而,由以上代码可知,这时候它调用的是objectA.a(),也就是由原来的bean来调用a()方法了,所以代码跑到了“标记1”。由此可见,“标记2”并没有被执行到,所以startTransaction()方法也没有运行。

 解决办法:

方案一:解决方法可以是直接在调用类中添加@Transactional注解insertBaseProject()

方案二@EnableAspectJAutoProxy(exposeProxy = true)在启动类中添加,会由Cglib代理实现。

在pom.xml 添加cglib 相关依赖

   <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency>

Application 程序入口 添加

@EnableAspectJAutoProxy(exposeProxy = true)
package cn.zzg.mybatisplus;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.transaction.annotation.EnableTransactionManagement;@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableTransactionManagement
@MapperScan({"cn.zzg.mybatisplus.mapper"})
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

服务类调整后,事务生效代码片段

    @Overridepublic boolean insertBaseProject(BaseProjectPO baseProject) {//return this.insertTrans(baseProject);return ((BaseProjectServiceImpl) AopContext.currentProxy()).insertTrans(baseProject);}

方案三: 使用ApplicationContext 获取Sevice 实现类

package cn.zzg.mybatisplus.components;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class ApplicationContetxtHolder implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {ApplicationContetxtHolder.context = applicationContext;}public static ApplicationContext getContext(){return context;}
}

 在BaseProjectServiceImpl服务实现类中如下实现:

    @Overridepublic boolean insertBaseProject(BaseProjectPO baseProject) {//return this.insertTrans(baseProject);//return ((BaseProjectServiceImpl) AopContext.currentProxy()).insertTrans(baseProject);BaseProjectServiceImpl service = ApplicationContetxtHolder.getContext().getBean(BaseProjectServiceImpl.class);return service.insertTrans(baseProject);}

在Controller调用该方法

    @GetMapping("/insert")public boolean insert() {BaseProjectPO po = new BaseProjectPO();po.setId("6");po.setTid("6");po.setPtid("6");po.setProjectNo("6");po.setProjectName("6");return service.insertBaseProject(po);}

 4. 方法使用 final 或 static关键字

如果Spring使用了Cglib代理实现(比如你的代理类没有实现接口),而你的业务方法恰好使用了final或者static关键字,那么事务也会失败。更具体地说,它应该抛出异常,因为Cglib使用字节码增强技术生成被代理类的子类并重写被代理类的方法来实现代理。如果被代理的方法的方法使用finalstatic关键字,则子类不能重写被代理的方法。

如果Spring使用JDK动态代理实现,JDK动态代理是基于接口实现的,那么finalstatic修饰的方法也就无法被代理。

总而言之,方法连代理都没有,那么肯定无法实现事务回滚了。

解决办法

方法去掉final或者static关键字

5. 方法不是public

如果方法不是publicSpring事务也会失败,因为Spring的事务管理源码AbstractFallbackTransactionAttributeSource中有判断computeTransactionAttribute()。如果目标方法不是公共的,则TransactionAttribute返回null

// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null;
}

解决办法

方法访问级别修改为publi

6. 错误使用传播机制

Spring事务的传播机制是指在多个事务方法相互调用时,确定事务应该如何传播的策略。Spring提供了七种事务传播机制:REQUIREDSUPPORTSMANDATORYREQUIRES_NEWNOT_SUPPORTEDNEVERNESTED。如果不知道这些传播策略的原理,很可能会导致交易失败。

@Service
public class TransactionService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate AddressMapper addressMapper;@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)public  void doInsert(User user,Address address) throws Exception {//do somethinguserMapper.insert(user);saveAddress(address);}@Transactional(propagation = Propagation.REQUIRES_NEW)public  void saveAddress(Address address) {//do somethingaddressMapper.insert(address);}
}

在上面的例子中,如果用户插入失败,不会导致saveAddress()回滚,因为这里使用的传播是REQUIRES_NEW,传播机制REQUIRES_NEW的原理是如果当前方法中没有事务,就会创建一个新的事务。如果一个事务已经存在,则当前事务将被挂起,并创建一个新事务。在当前事务完成之前,不会提交父事务。如果父事务发生异常,则不影响子事务的提交。

事务的传播机制说明如下:REQUIRED 如果当前上下文中存在事务,那么加入该事务,如果不存在事务,创建一个事务,这是默认的传播属性值。
SUPPORTS 如果当前上下文存在事务,则支持事务加入事务,如果不存在事务,则使用非事务的方式执行。
MANDATORY 如果当前上下文中存在事务,否则抛出异常。
REQUIRES_NEW 每次都会新建一个事务,并且同时将上下文中的事务挂起,执行当前新建事务完成以后,上下文事务恢复再执行。
NOT_SUPPORTED 如果当前上下文中存在事务,则挂起当前事务,然后新的方法在没有事务的环境中执行。
NEVER 如果当前上下文中存在事务,则抛出异常,否则在无事务环境上执行代码。
NESTED 如果当前上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务。

解决办法

将事务传播策略更改为默认值REQUIREDREQUIRED原理是如果当前有一个事务被添加到一个事务中,如果没有,则创建一个新的事务,父事务和被调用的事务在同一个事务中。即使被调用的异常被捕获,整个事务仍然会被回滚。

7.没有被Spring管理


//@Service(value = "baseProjectServiceImpl")
public class BaseProjectServiceImpl extends ServiceImpl<BaseProjectMapper, BaseProjectPO> implements IBaseProjectService {******
}

此时把 @Service 注解注释掉,这个类就不会被加载成一个 Bean,那这个类就不会被 Spring 管理了,事务自然就失效了。

解决办法

保证每个事务注解的每个Bean被Spring管理。

Spring 编程事务

编程事务实现方式:

  1. 使用TransactionTemplate 或 TransactionalOperator
  2. 直接创建TransactionManager的实现

官方推荐使用TransactionTemplate 方式。本章节也是重点讲解TransactionTemplate 使用

TransactionTemplate

带返回值

@Service 
public class UserService { @Resource private TransactionTemplate transactionTemplate ; @Resource private UsersRepository usersRepository ; public Integer saveUsers(Users users) { this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); Integer result = transactionTemplate.execute(new TransactionCallback<Integer>() { @Override public Integer doInTransaction(TransactionStatus status) { return usersMapper.insertUser(users) ; } }) ; return result ; } } 

无返回值

public void saveUsers(Users users) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { usersMapper.insertUser(users) ; } }) ; 
} 

事务回滚

public Users saveUser(Users users) { return transactionTemplate.execute(new TransactionCallback<Users>() { @Override public Users doInTransaction(TransactionStatus status) { try { return usersMapper.insertUser(users) ; } catch (Exception e) { status.setRollbackOnly() ; } return null ; } }) ; 
} 

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

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

相关文章

Quartz与Spring Task的区别

1、相同点&#xff1a; 两者均能实现定时调度任务 2、Quartz ① 默认多线程异步执行 ② 单个任务时&#xff0c;在上一个调度未完成时&#xff0c;下一个调度时间到时&#xff0c;会另起一个线程开始新的调度。业务繁忙时&#xff0c;一个任务会有多个调度&#xff0c;可能导…

DAY65: 图论入门797、200、695

深度优先搜索 深度优先搜索按照一个方向一直搜索直到截止&#xff0c;再回溯换搜索方向。 搜索方向&#xff0c;是认准一个方向搜&#xff0c;直到碰壁之后再换方向换方向是撤销原路径&#xff0c;改为节点链接的下一个路径&#xff0c;回溯的过程 因为需要回溯&#xff0c;…

【STM32】STM32学习笔记-独立看门狗和窗口看门狗(47)

00. 目录 文章目录 00. 目录01. WDG概述02. 独立看门狗相关API2.1 IWDG_WriteAccessCmd2.2 IWDG_SetPrescaler2.3 IWDG_SetReload2.4 IWDG_ReloadCounter2.5 IWDG_Enable2.6 IWDG_GetFlagStatus2.7 RCC_GetFlagStatus 03. 独立看门狗接线图04. 独立看门狗程序示例105. 独立看门…

简单排列组合题(python版)

文章预览&#xff1a; 题目解法一输出结果 解法二输出结果输出结果 题目 有四个数字:1,2,3,4能组成多少个互不相同且无重复的数字的三位数? 各式多少? 解法一 我们粗略看一下这个题既然我们要组成三位数&#xff0c;那我们就循环3层每一层出一个数&#xff0c;并且if语句判…

OD(12)之Mermaid思维导图(Mindmap)

OD(12)之Mermaid思维导图(Mindmap)使用详解 Author: Once Day Date: 2024年2月29日 漫漫长路才刚刚开始… 全系列文章可参考专栏: Mermaid使用指南_Once_day的博客-CSDN博客 参考文章: 关于 Mermaid | Mermaid 中文网 (nodejs.cn)Mermaid | Diagramming and charting tool…

postman传参与返回值切换为左右显示的操作

目录 第一步 点击“Settings”&#xff0c;在下拉框选择“Settings” 第二步 在默认打开的General页面&#xff0c;参照下图改动两处 第一步 点击“Settings”&#xff0c;在下拉框选择“Settings” 第二步 在默认打开的General页面&#xff0c;参照下图改动两处 附上修改后…

字符串函数strstr()详解

一、strstr()函数的作用 字符串函数 strstr() 是 C 语言的一个标准库函数&#xff0c;它的作用是在一个字符串中查找给定字符串的第一个匹配之处&#xff0c;并返回指向该字符串的指针。如果没有找到该字符串&#xff0c;则返回 NULL。1 二、strstr()函数的原型和参数 strst…

c语言求奇数分之一序列前N项和

本题要求编写程序&#xff0c;计算序列 1 1/3 1/5 ... 的前N项之和。 输入格式: 输入在一行中给出一个正整数N。 输出格式: 在一行中按照“sum S”的格式输出部分和的值S&#xff0c;精确到小数点后6位。题目保证计算结果不超过双精度范围。 输入样例: 23输出样例: …

opencv中的rgb转gray的计算方法

转换原理 在opencv中&#xff0c;可以使用cv2.cvtColor函数将rgb图像转换为gray图像。示例代码如下&#xff0c; import cv2img_path "image.jpg" image cv2.imread(img_path) gray_image cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) mean gray_image.mean() pri…

【AI Agent系列】【MetaGPT多智能体学习】4. 基于MetaGPT的Team组件开发你的第一个智能体团队

本系列文章跟随《MetaGPT多智能体课程》&#xff08;https://github.com/datawhalechina/hugging-multi-agent&#xff09;&#xff0c;深入理解并实践多智能体系统的开发。 本文为该课程的第四章&#xff08;多智能体开发&#xff09;的第二篇笔记。主要是对MetaGPT中Team组件…

【Django】执行查询—检索对象

检索对象 检索全部对象 >>> all_entries Entry.objects.all()通过过滤器检索指定对象 通过添加过滤条件精炼原始 QuerySet。两种最常见的精炼 QuerySet 的方式是&#xff1a; filter(**kwargs) 返回一个新的 QuerySet&#xff0c;包含的对象满足给定查询参数。 ex…

【Tomcat】在 linux 上实现 Catlina.log 自动分割,防止文件过大

背景描述 catalina.out即标准输出和标准出错&#xff0c;所有输出到这两个位置的都会进入catalina.out&#xff0c;这里包含tomcat运行自己输出的日志以及应用里向console输出的日志。默认这个日志文件是不会进行自动切割的&#xff0c;所以我们需要借助其他工具进行切割&…

MySQL:快照读和当前读

mysql读取数据实际上有两种读取模式&#xff1a;当前读和快照读 快照读&#xff1a;快照读的执行方式是生成 ReadView&#xff0c;直接利用 MVCC 机制来进行读取&#xff0c;并不会对记录进行加锁。当前读&#xff1a;每次读取的都是当前最新的数据&#xff0c;但是读的时候不…

剑指offer面试题22 栈的压入弹出序列

考察点 辅助栈知识点 题目 分析 这道题目要求输入俩个序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;要求判断第二个序列是否是该栈的弹出顺序。遇到这类题目思维一定要往辅助栈上靠&#xff0c;因为关于栈的考点其实就是这个。这种题目的解题思路就是归纳&#x…

「Python系列」Python pyecharts模块

文章目录 一、pyecharts安装二、pyecharts应用三、pyecharts图表类型四、pyecharts特点与功能特点&#xff1a;功能&#xff1a; 五、相关链接 一、pyecharts安装 要安装 Python 的 pyecharts 模块&#xff0c;你可以使用 pip&#xff0c;这是 Python 的包管理工具。请按照以下…

Payment Without Change

题目链接&#xff1a;Problem - 1256A - Codeforces 解题思路&#xff1a; 题目的大致意思就是手中的硬币数拿出若干枚正好等于s&#xff0c;分三种情况 .如果n > s && b < s,输出no .如果b > s,输出yes .如果n * (a < (s / n) ? a : (s / n)) b >…

数据结构(C语言版)02---链表

链表&#xff1a; 声明&#xff1a;LNode* LinkList在链表里面这两个是等价的; #include<stdio.h> #include<stdlib.h> typedef int Elemtype; typedef struct LNode{Elemtype data;struct LNode* next; }LNode,*LinkList; 链表打印函数&#xff1a; //打印v…

【iOS ARKit】RealityKit 同步机制

协作 Session 可以很方便地实现多用户之间的AR体验实时共享&#xff0c;但开发者需要自行负责并确保AR场景的完整性&#xff0c;自行负责虚拟物体的创建与销毁。为简化同步操作&#xff0c;RealityKit 内建了同步机制&#xff0c;RealityKit 同步机制基于 Multipeer Connectivi…

Python标准库sys常用函数、方法及代码实战解析【第108篇—标准库sys常用函数】

Python标准库sys常用函数、方法及代码实战解析 在Python的标准库中&#xff0c;sys 模块是一个常用而强大的工具&#xff0c;它提供了与Python解释器交互的函数和变量。本文将介绍sys模块的一些常用函数和方法&#xff0c;并通过实际的代码实例来解析它们的用法。 1. sys.argv…

C语言统计文件夹下所有文件数量/C语言删除文件夹下所有文件

代码解法不唯一&#xff0c;欢迎在评论区留下你的实现方式和想法&#xff0c;我会将好的解法更新到文章中&#xff01;&#xff01; 在C语言中&#xff0c;可以使用标准库中的函数来完成对文件夹中文件数量的判断和删除操作。下面是使用POSIX标准的代码示例&#xff0c;这段代…