Spring框架的事务管理
引言
在企业级应用开发中,事务管理是一个至关重要的环节,它确保了数据的一致性和完整性。Spring 框架为我们提供了强大而灵活的事务管理功能,能够帮助开发者更轻松地处理复杂的事务场景。本文将深入探讨 Spring 框架的事务管理,包括相关的类和 API,以及声明式事务管理的实现方式,并结合具体代码示例进行详细解释。
1. Spring 框架的事务管理相关的类和 API
1.1 PlatformTransactionManager 接口
PlatformTransactionManager
是 Spring 框架中用于管理事务的核心接口,它定义了事务的基本操作,如提交和回滚。该接口有具体的实现类,我们需要根据不同的持久层框架选择合适的实现类。
接口方法
void commit(TransactionStatus status)
:用于提交事务。void rollback(TransactionStatus status)
:用于回滚事务。
实现类选择
- DataSourceTransactionManager:如果使用 Spring 的 JDBC 模板或者 MyBatis 框架,应选择这个实现类。因为这些框架都是基于数据源(DataSource)进行数据库操作的,
DataSourceTransactionManager
可以很好地与数据源集成,管理事务。 - HibernateTransactionManager:当使用 Hibernate 框架时,需要选择这个实现类。它专门为 Hibernate 的事务管理而设计,能够与 Hibernate 的会话(Session)和事务机制无缝对接。
1.2 TransactionDefinition 接口
TransactionDefinition
接口定义了事务的一些基本属性,包括事务隔离级别和事务传播行为。
事务隔离级别
事务隔离级别用于控制多个事务之间的可见性和并发访问。常见的隔离级别有:
ISOLATION_DEFAULT
:使用数据库的默认隔离级别。ISOLATION_READ_UNCOMMITTED
:允许读取未提交的数据,可能会导致脏读、不可重复读和幻读问题。ISOLATION_READ_COMMITTED
:只能读取已提交的数据,避免了脏读,但仍可能出现不可重复读和幻读。ISOLATION_REPEATABLE_READ
:保证在同一个事务中多次读取同一数据的结果是一致的,避免了脏读和不可重复读,但仍可能出现幻读。ISOLATION_SERIALIZABLE
:最高的隔离级别,所有事务依次执行,避免了脏读、不可重复读和幻读,但会降低并发性能。
事务传播行为
事务传播行为定义了在一个事务方法调用另一个事务方法时,事务应该如何处理。常见的传播行为有:
PROPAGATION_REQUIRED
:如果当前存在事务,则加入该事务;如果不存在,则创建一个新的事务。PROPAGATION_SUPPORTS
:如果当前存在事务,则加入该事务;如果不存在,则以非事务方式执行。PROPAGATION_MANDATORY
:如果当前存在事务,则加入该事务;如果不存在,则抛出异常。PROPAGATION_REQUIRES_NEW
:无论当前是否存在事务,都创建一个新的事务,并挂起当前事务。PROPAGATION_NOT_SUPPORTED
:以非事务方式执行,如果当前存在事务,则挂起该事务。PROPAGATION_NEVER
:以非事务方式执行,如果当前存在事务,则抛出异常。PROPAGATION_NESTED
:如果当前存在事务,则在嵌套事务中执行;如果不存在,则创建一个新的事务。
2. Spring 框架声明式事务管理
2.1、XML 配置方式
1. 配置文件
jdbc.properties
:存储数据库连接信息,包括驱动类名、URL、用户名和密码。
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?useSSL=false&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
applicationContext.xml
:核心配置文件,主要完成以下配置:- 加载属性文件:通过
<context:property - placeholder>
加载jdbc.properties
。 - 配置数据源:使用 Druid 数据源,将属性文件中的配置注入。
- 配置平台事务管理器:使用
DataSourceTransactionManager
,并关联数据源。 - 配置事务通知:通过
<tx:advice>
定义事务属性,如pay
方法使用事务,find*
方法只读。 - 配置 AOP:通过
<aop:config>
定义切入点和通知的关联。 - 配置 Service 和 Dao:将 Service 和 Dao 作为 Bean 注册到 Spring 容器中,并进行依赖注入。
- 加载属性文件:通过
<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 加载属性文件 --><context:property-placeholder location="classpath:jdbc.properties"/><!-- 配置数据源 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.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><!-- pay 方法使用事务 --><tx:method name="pay" isolation="DEFAULT" propagation="REQUIRED"/><!-- find 开头的方法只读 --><tx:method name="find*" read-only="true"/></tx:attributes></tx:advice><!-- 配置 AOP --><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(public * com.qcbyjy.demo4.AccountServiceImpl.pay(..))"/></aop:config><!-- 配置 Service --><bean id="accountService" class="com.qcbyjy.demo1.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><!-- 配置 Dao --><bean id="accountDao" class="com.qcbyjy.demo1.AccountDaoImpl"><property name="dataSource" ref="dataSource"/></bean>
</beans>
2.Java类
AccountDao.java
:定义数据访问接口,包含outMoney
、inMoney
和findMoney
方法。
package com.qcbyjy.demo1;public interface AccountDao {void outMoney(String out, double money);void inMoney(String in, double money);double findMoney(String name);
}
AccountDaoImpl.java
:实现AccountDao
接口,通过JdbcDaoSupport
进行数据库操作。
package com.qcbyjy.demo1;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {@Overridepublic void outMoney(String out, double money) {String sql = "update account set money=money-? where name=?";this.getJdbcTemplate().update(sql, money, out);}@Overridepublic void inMoney(String in, double money) {String sql = "update account set money=money+? where name=?";this.getJdbcTemplate().update(sql, money, in);}@Overridepublic double findMoney(String name) {String sql = "select money from account where name=?";return this.getJdbcTemplate().queryForObject(sql, Double.class, name);}
}
AccountService.java
:定义业务服务接口,包含pay
和checkBalance
方法。
package com.qcbyjy.demo1;public interface AccountService {void pay(String out, String in, double money);double checkBalance(String name);
}
AccountServiceImpl.java
:实现AccountService
接口,调用AccountDao
完成业务逻辑。
package com.qcbyjy.demo1;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void pay(String out, String in, double money) {accountDao.outMoney(out, money);// 模拟异常,测试事务回滚// int a = 1/0;accountDao.inMoney(in, money);}@Overridepublic double checkBalance(String name) {return accountDao.findMoney(name);}
}
3.测试
package com.qcbyjy.test.demo1;import com.qcbyjy.demo1.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo1 {@Testpublic void testXmlTransaction(){ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");AccountService accountService =(AccountService) context.getBean("accountService");System.out.println("XML配置方式事务测试...");try {accountService.pay("aaa", "ccc", 100);System.out.println("转账成功!");} catch (Exception e) {System.out.println("转账失败,事务已回滚:" + e.getMessage());}}
}
4. 重要知识点
- 事务通知和 AOP 配置:通过
<tx:advice>
定义事务属性,再通过<aop:config>
将事务通知应用到指定的切入点,实现事务的织入。 - 属性占位符:
<context:property - placeholder>
可以方便地加载属性文件,将配置信息从 XML 文件中分离出来,提高配置的可维护性。
2.2、XML + 注解方式
1. 配置文件
applicationContext_1.xml
:主要完成以下配置:- 开启注解扫描:通过
<context:component - scan>
扫描指定包下的注解组件。 - 加载属性文件:同 XML 配置方式。
- 配置数据源和事务管理器:同 XML 配置方式。
- 配置 Jdbc 模板:为 Dao 层提供数据库操作模板。
- 开启事务注解支持:通过
<tx:annotation - driven>
开启@Transactional
注解的支持。
- 开启注解扫描:通过
<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 开启注解扫描 --><context:component-scan base-package="com.qcbyjy.demo2"/><!-- 加载属性文件 --><context:property-placeholder location="classpath:db.properties"/><!-- 配置数据源 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!-- 配置平台事务管理器 --><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 配置Jdbc模板 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean><!-- 开启事务注解支持 --><tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
2. Java 类
AccountDao.java
:同 XML 配置方式。AccountDaoImpl.java
:使用@Repository
注解将该类注册为 Spring Bean,并通过@Autowired
注入JdbcTemplate
。
package com.qcbyjy.demo2;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;@Repository
public class AccountDaoImpl implements AccountDao {@Autowiredprivate JdbcTemplate jdbcTemplate;/***付款*@paramout*@parammoney*/public void outMoney(String out,double money){String sql="update account set money=money - ? where name = ?";jdbcTemplate.update(sql,money,out);}/***收款*@paramin*@parammoney*/public void inMoney(String in,double money){String sql="update account set money=money +? where name= ?";jdbcTemplate.update(sql,money,in);}}
AccountService.java
:同 XML 配置方式。AccountServiceImpl.java
:使用@Service
注解将该类注册为 Spring Bean,并使用@Transactional
注解定义事务属性。
package com.qcbyjy.demo2;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;@Service
@Transactional(isolation = Isolation.DEFAULT)
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;/***转账方法*@paramout付款人*@paramin收款人*@parammoney金额*/public void pay(String out,String in,double money){accountDao.outMoney(out,money);// 模拟异常
// int a = 1/0;accountDao.inMoney(in,money);}}
3.测试
package com.qcbyjy.test.demo2;import com.qcbyjy.demo2.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo2 {@Testpublic void testAnnotationTransaction(){ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext_1.xml");AccountService accountService=context.getBean(AccountService.class);System.out.println("XML+注解方式事务测试...");try {accountService.pay("ccc", "aaa", 100);System.out.println("转账成功!");} catch (Exception e) {System.out.println("转账失败,事务已回滚:" + e.getMessage());}}
}
4. 重要知识点
- 注解扫描:
<context:component - scan>
可以自动扫描指定包下的@Component
、@Repository
、@Service
和@Controller
注解的类,并将它们注册为 Spring Bean。 @Transactional
注解:用于定义事务属性,如隔离级别、传播行为、是否只读等。可以应用在类或方法上,应用在类上时,该类的所有公共方法都将应用该事务属性。
2.3、纯注解方式
1. Java 配置类
SpringConfig.java
:使用@Configuration
注解将该类标记为配置类,通过@ComponentScan
扫描指定包下的注解组件,使用@EnableTransactionManagement
开启事务注解支持,并通过@Bean
方法定义数据源、Jdbc 模板和事务管理器。
package com.qcbyjy.demo3;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.annotation.Resource;
import javax.sql.DataSource;@Configuration
@ComponentScan(basePackages = "com.qcbyjy.demo3")
@EnableTransactionManagement
public class SpringConfig {@Bean(name="dataSource")public DataSource dataSource() {// 创建连接池对象,Spring框架内置了连接池对象DruidDataSource dataSource = new DruidDataSource();// 设置4个参数dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/spring_db?useSSL=false&characterEncoding=utf8");dataSource.setUsername("root");dataSource.setPassword("12345");return dataSource;}@Resource(name="dataSource")@Bean(name="jdbcTemplate")public JdbcTemplate createJdbcTemplate(DataSource dataSource){JdbcTemplate template =new JdbcTemplate(dataSource);return template;}@Resource(name="dataSource")@Bean(name="transactionManager")public PlatformTransactionManager createTransactionManager(DataSource dataSource) {DataSourceTransactionManager manager = new DataSourceTransactionManager(dataSource);return manager;}// @Bean
// public JdbcTemplate jdbcTemplate(DataSource dataSource) {
// return new JdbcTemplate(dataSource);
// }// @Bean
// public PlatformTransactionManager transactionManager(DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
}
2. Java 类
AccountDao.java
、AccountDaoImpl.java
、AccountService.java
和AccountServiceImpl.java
:同 XML + 注解方式。
3.测试
package com.qcbyjy.test.Demo3;import com.qcbyjy.demo3.AccountService;
import com.qcbyjy.demo3.SpringConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo3 {@Testpublic void testPureAnnotationTransaction() {AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);AccountService accountService=context.getBean(AccountService.class);System.out.println("纯注解方式事务测试...");try {accountService.pay("aaa", "ccc", 1000);System.out.println("转账成功!");} catch (Exception e) {System.out.println("转账失败,事务已回滚:" + e.getMessage());}context.close();}
}
4. 重要知识点
- Java 配置类:使用
@Configuration
注解的类可以替代 XML 配置文件,通过@Bean
方法定义 Bean,提高配置的灵活性和可维护性。 @EnableTransactionManagement
:开启 Spring 的事务注解支持,使得@Transactional
注解生效。
4.事务特性验证
三种方式都可以通过取消注释模拟异常的代码(int a = 1/0;
)来测试事务回滚功能。每次测试前后会打印账户余额,验证事务是否正常工作。同时,需要创建 spring_db
数据库和 account
表,并初始化张三和李四的账户余额为 1000。
5.总结
- XML 配置方式:适合于对配置细节有严格要求,且团队对 XML 配置比较熟悉的场景。通过 XML 可以清晰地定义事务的各个方面,但配置文件可能会变得冗长和复杂。
- XML + 注解方式:结合了 XML 配置的灵活性和注解的简洁性,XML 负责全局配置,注解负责局部配置,是一种比较常用的方式。
- 纯注解方式:适合于追求代码简洁性和开发效率的场景,完全基于 Java 配置和注解,减少了 XML 配置文件的使用,但对开发者的 Java 配置能力要求较高。
相关文章:
Spring框架的事务管理
引言 在企业级应用开发中,事务管理是一个至关重要的环节,它确保了数据的一致性和完整性。Spring 框架为我们提供了强大而灵活的事务管理功能,能够帮助开发者更轻松地处理复杂的事务场景。本文将深入探讨 Spring 框架的事务管理,包…...
TypeScript:类
一、基本概念 TypeScript 类是基于 ES6 类的语法扩展,增加了类型注解和访问修饰符等特性,提供了更强大的面向对象编程能力。 二、基本语法 class Person {name: string;age: number;constructor(name: string, age: number) {this.name name;this.ag…...
Python继承
在Python编程中,继承是一个让新手又爱又怕的概念。今天我们就来聊聊这个看似高深实则简单的特性,保证让你看完后能拍着胸脯说:“继承嘛,小菜一碟!” 一、什么是继承? 想象一下你正在玩一个养成游戏。你创…...
浏览器宝塔访问不了给的面板地址
注意你们的端口,服务器的端口开放了没!!!宝塔给的端口是否在范围之内!! 我的当时是1000/10000 (阿里云服务器) 但是宝塔给的是 4W多 对不上!! 更换安全组…...
强化学习入门:马尔科夫奖励过程
文章目录 前言1、组成部分2、应用例子3、马尔科夫奖励过程总结 前言 最近想开一个关于强化学习专栏,因为DeepSeek-R1很火,但本人对于LLM连门都没入。因此,只是记录一些类似的读书笔记,内容不深,大多数只是一些概念的东…...
RHCE实验:通过脚本判断用户是否存在
一、实验要求 1、 写一个脚本,使用函数完成 1 、函数能够接受一个参数,参数为用户名; 判断一个用户是否存在 如果存在, 就返回此用户的 shell 和 UID ;并返回正常状态值; 如果不存在,就说此用…...
Windows软件插件-音视频捕获
下载本插件 音视频捕获就是获取电脑外接的话筒,摄像头,或线路输入的音频和视频。 本插件捕获电脑外接的音频和视频。最多可以同时获取4个视频源和4个音频源。插件可以在win32和MFC程序中使用。 使用方法 首先,加载本“捕获”DLL,…...
每日算法 - 【Swift 算法】Two Sum 问题:从暴力解法到最优解法的演进
【Swift 算法】Two Sum 问题:从暴力解法到最优解法的演进 本文通过“Two Sum”问题,带你了解如何从最直观的暴力解法,逐步优化到高效的哈希表解法,并对两者进行对比,适合算法入门和面试准备。 💡 问题描述 …...
2025年,如何制作并部署一个完整的个人博客网站
欢迎访问我的个人博客网站:欢迎来到Turnin的个人博客 github开源地址:https://github.com/Re-restart/my_website 前言 2024年年初,从dji实习回来之后,我一直想着拓宽自己的知识边界。在那里我发现虽然大家不用java,…...
深度学习框架---TensorFlow概览
一、TensorFlow 概述 1. 发展历程 1.x 版本:基于静态图(Graph)和会话(Session),需预先定义计算图,调试较复杂。2.x 版本:默认启用动态图(Eager Execution)&…...
鸿蒙OSUniApp制作自定义的下拉菜单组件(鸿蒙系统适配版)#三方框架 #Uniapp
UniApp制作自定义的下拉菜单组件(鸿蒙系统适配版) 前言 在移动应用开发中,下拉菜单是一个常见且实用的交互组件,它能在有限的屏幕空间内展示更多的选项。虽然各种UI框架都提供了下拉菜单组件,但在一些特定场景下&…...
扣子(Coze)案例:工作流生成小红书心理学卡片
大家好!我是 Robin。专注于 AI 技术探索与实践,持续分享 Coze 智能体、Coze 模板,以及 Coze 工作流搭建案例。 工作流智能体作用: 输入需要生成小红书心理学知识卡片的数量,工作流自动批量生成图文。 首先演示一下生…...
深度理解用于多智能体强化学习的单调价值函数分解QMIX算法:基于python从零实现
引言:合作式多智能体强化学习与功劳分配 在合作式多智能体强化学习(MARL)中,多个智能体携手合作,共同达成一个目标,通常会收到一个团队共享的奖励。在这种场景下,一个关键的挑战就是功劳分配&a…...
C语言经典笔试题目分析(持续更新)
1. 描述下面代码中两个static 各自的含义 static void func (void) {static unsigned int i; }static void func(void) 中的 static 作用对象:函数 func。 含义: 限制函数的作用域(链接属性),使其仅在当前源文件&…...
射击游戏demo11
完善地图,加载出装饰品,检测人员与地面的碰撞,检测子弹与岩壁的碰撞,检测手雷与地面的碰撞。 import pygame import sys import os import random import csv # 初始化Pygame pygame.init()# 屏幕宽度 SCREEN_WIDTH 1200 # 屏幕高…...
多智能体Multi-Agent应用实战与原理分析
一:Agent 与传统工具调用的对比 在当今的开发环境中,Agent 的出现极大地简化了工作流程。其底层主要基于提示词、模型和工具。用户只需向 Agent 输入需求,Agent 便会自动分析需求,并利用工具获取最终答案。而传统方式下,若没有 Agent,我们则需要手动编码来执行工具,还要…...
专项智能练习(定义判断)_DA_01
1. 单选题 热传导是介质内无宏观运动时的传热现象,其在固体、液体和气体中均可发生。但严格而言,只有在固体中才是纯粹的热传导,在流体(泛指液体和气体)中又是另外一种情况,流体即使处于静止状态࿰…...
关于NLP自然语言处理的简单总结
参考: 什么是自然语言处理?看这篇文章就够了! - 知乎 (zhihu.com) 所谓自然语言理解,就是研究如何让机器能够理解我们人类的语言并给出一些回应。 自然语言处理(Natural Language Processing,NLP࿰…...
SLAM定位与地图构建
SLAM介绍 SLAM全称Simultaneous Localization And Mapping,中文名称同时定位与地图构建。旨在让移动设备在未知环境中同时完成以下两个任务(定位需要地图,而建图又依赖定位信息,两者互为依赖): 定位&#…...
REST架构风格介绍
一.REST(表述性状态转移) 1.定义 REST(Representational State Transfer)是由 Roy Fielding 在 2000 年提出的一种软件架构风格,用于设计网络应用的通信模式。它基于 HTTP 协议,强调通过统一的接口&#…...
前端流行框架Vue3教程:16. 组件事件配合`v-model`使用
组件事件配合v-model使用 如果是用户输入,我们希望在获取数据的同时发送数据配合v-model 来使用,帮助理解组件间的通信和数据绑定。 🧩 第一步:创建子组件(SearchComponent.vue) 这个组件用于处理用户的搜…...
5月15日day26打卡
函数专题1 知识点回顾: 函数的定义变量作用域:局部变量和全局变量函数的参数类型:位置参数、默认参数、不定参数传递参数的手段:关键词参数传递参数的顺序:同时出现三种参数类型时 作业: 题目1:…...
Java中的深拷贝与浅拷贝
什么是拷贝 在Java中,拷贝是指创建一个对象的副本。拷贝主要分为两种类型:浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。理解这两种拷贝的区别对于编写正确的Java程序非常重要,特别是在处理对象引用时。 浅拷贝(Shallow Copy) 浅拷贝是指创建…...
springboot AOP中,通过解析SpEL 表达式动态获取参数值
切面注解 import com.bn.document.constants.FmDeptCatalogueConstants;import java.lang.annotation.*;Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface FmDeptCatalogueAopAnnotation {/*** 权限类型*/FmDeptCatalogueConstants value();/…...
【论信息系统项目的合同管理】
论信息系统项目的合同管理 论文要求写作要点正文前言一、合同的签订管理二、合同履行管理三、合同变更管理四、合同档案管理五、合同违约索赔管理结语 论文要求 项目合同管理通过对项目合同的全生命周期进行管理,来回避和减轻可识别的项目风险。 请以“论信息系统项…...
redis持久化方式
一、RDB redis database:快照,某一时刻将内存中的数据,写入磁盘中生成1个dump.rdb文件RDB的触发方式: 手动触发:save(阻塞主进程,阻塞其它指令,保证数据一致性)、bgsave…...
free void* 指令
https://stackoverflow.com/questions/2182103/is-it-ok-to-free-void free(ptr) 仅释放指针指向的内存,不会修改指针变量本身的值。调用后,ptr 仍然指向原来的地址(称为 "悬空指针"),但该地址对应的内存已…...
ADS1220高精度ADC(TI)——应用 源码
文章目录 德州仪器ADS1220概述资料引脚&封装布线寄存器配置寄存器0(00h)配置寄存器1(01h)配置寄存器2(02h)配置寄存器3(03h) 连续转换流程驱动源码ads1220.cads1220.h 德州仪器A…...
mysql-Java手写分布式事物提交流程
准备 innodb存储引擎开启支持分布式事务 set global innodb_support_axon分布式的流程 详细流程: XA START ‘a’; 作用:开始一个新的XA事务,并分配一个唯一的事务ID ‘a’。 说明:在这个命令之后,所有后续的SQL操…...
红黑树:数据世界的平衡守护者
在 C 算法的神秘森林里,红黑树是一棵充满智慧的 “魔法树”。它既不像普通二叉搜索树那样容易失衡,也不像 AVL 树对平衡要求那么苛刻。作为 C 算法小白,今天就和大家一起深入探索红黑树的奥秘,看看它是如何成为数据世界的平衡守护…...
哈夫曼树完全解析:从原理到应用
目录 一、核心概念 二、构造全流程解析 三、编码生成机制 四、C语言实现关键代码 五、核心特性深度解读 六、现代应用场景 七、压缩实战演示 一、核心概念 哈夫曼树(最优二叉树)是带权路径长度(WPL)最短的树形结构&#x…...
如何在 Windows 命令提示符中创建多个文件夹和多个文件
如何在 Windows 命令提示符中创建多个文件夹和多个文件 虽然大多数用户习惯使用 Windows 图形界面来创建文件夹,但如果你需要一次性创建多个文件夹或文件,如同在类Unix系统中可以使用mkdir和touch命令一样,windows下也有创建目录和文件的对应…...
【Java】Spring的声明事务在多线程场景中失效问题。
大家都知道Spring的声明式事务在多线程当中会失效,来看一下如下案例。 按照如下方式,b()方法抛出异常,由于父子线程导致事务失效,a()会成功插入,但是b()不会。 因此成功插入一条数据,事务失效。 Component public class UserServ…...
多平台图标设计与管理的终极解决方案
IconWorkshop Pro 是一款由Axialis团队开发的专业图标设计与制作软件,专注于为设计师、开发者及企业用户提供高效且灵活的图标创作解决方案。该软件凭借其强大的功能与跨平台适配性,成为Windows、macOS、iOS、Android等多系统图标设计的首选工具之一。 …...
【搭建Node-RED + MQTT Broker实现AI大模型交互】
搭建Node-RED MQTT Broker实现AI大模型交互 搭建Node-RED MQTT Broker实现AI大模型交互一、系统架构二、环境准备与安装1. 安装Node.js2. 安装Mosquitto MQTT Broker3. 配置Mosquitto4. 安装Node-RED5. 配置Node-RED监听所有网络接口6. 启动Node-RED 三、Node-RED流程配置1. …...
小结: js 在浏览器执行原理
浏览器多进程与多线程 现代浏览器的标签环境隔离主要通过多进程架构和多线程机制实现,以确保安全、性能和稳定性。以下是浏览器实现标签环境隔离的多进程和多线程交互架构的详细解析: ------------------- ------------------- -----------…...
C++核心编程--2 引用
引用就是给变量起别名,操作引用就等于操作原始变量。 2.1 引用基本用法 int var 10; int & r_var var; 2.2 注意事项 声明时必须初始化不允许更改引用指向的原始变量 2.3 引用作为函数参数传递 简化指针修饰函数参数 2.4 引用作为函数返回值 不要返回…...
音频/AI/BLE/WIFI/玩具/商业等方向的论坛网站总结
我爱音频网 我爱音频网 - 我们只谈音频,丰富的TWS真无线蓝牙耳机拆解报告 (52audio.com) 中国人工智能学会 中国人工智能学会 (caai.cn) AIIA人工智能网 https://www.aiiaw.com/ 世界人工智能论坛 世界人工智能论坛 - (amtbbs.org) 36氪 36氪_让一部分人先…...
告别碎片化!MCP 带来 AI Agent 开发生态的革命性突破
引言: 在当今的智能客服系统开发中,开发者常常面临一个棘手的挑战:需要整合用户的 CRM 数据、知识库和实时聊天记录。然而,由于缺乏统一的标准,每个团队都不得不手动实现这些集成。这不仅延长了开发周期,还…...
centos7部署mysql5.7
1.下载mysql的官方yum源 wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm2.安装yum源 yum -y install mysql57-community-release-el7-11.noarch.rpm3.安装秘钥文件 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-20224.安装mysql5.7…...
linux dbus
Linux D-Bus(Desktop Bus)是一种进程间通信(IPC)机制,主要用于Linux桌面环境和系统服务之间的消息传递。它允许不同的应用程序或系统组件以高效、安全的方式相互通信,是现代Linux桌面(如GNOME、KDE)的核心基础设施之一。 1. D-Bus 的核心概念 消息总线(Message Bus):…...
计量——异方差的检验及其修正
目录 1.异方差的检验 1 BP检验 2white检验 2.异方差的修正 1.异方差的检验 1 BP检验 选择检验方法:BP BP检验的实际步骤(非机器): 1.y对所有x进行回归,得到残差u。计算残差的平方u^2 2.u^2对所有x进行回归&#…...
操作系统学习笔记第3章 内存管理(灰灰题库)
1. 单选题 某页式存储管理系统中,主存为 128KB,分成 32 块,块号为 0、1、2、3、…、31。某作业有 5 块,其页号为 0、1、2、3、4,被分别装入主存的 3、8、4、6、9 块中。有一逻辑地址为 [3, 70](其中方括号中…...
vue3项目中使用CanvasEditor开箱即用(组件的形式,组件封装好了)
canvas-editor-vue 这是canvas-editor项目的vue版本,我封装成组建了,当然了这是个已经把canvas-editor封装好的的Vue项目 项目地址GitHub地址:GitHub - aini-aini/canvas-editor-vue: this is a project than can be used in vue project as Componentthis is a project than…...
人体肢体工作识别-一步几个脚印从头设计数字生命——仙盟创梦IDE
人体肢体识别是借助计算机视觉、传感器等技术,对人体各肢体的位置、动作、姿态等进行检测与分析的技术。其在医疗健康、智能交互、运动训练、安全监控等多个领域具有重要价值, 示例代码 import cv2 import mediapipe as mp import numpy as np import c…...
【重磅】配电网智能软开关和储能联合规划
目录 1 主要内容 目标函数 数据说明 节点系统图 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现《具有源荷不平衡特性的配电网智能软开关和储能联合规划》部分模型,未考虑聚类分析和分布鲁棒部分,就智能软开关和储能联合规划部分进行了…...
实验6 电子邮件
实验6 电子邮件 1、实验目的 理解电子邮件系统基本结构 理解客户端和服务器端,以及服务器之间的通信 分析理解SMTP,POP3协议 2、实验环境 硬件要求:阿里云云主机ECS 一台。 软件要求:Linux/ Windows 操作系统 3、实验内容…...
NHANES指标推荐:OBS
文章题目:Association between oxidative balance score and all-cause and cancer-specific mortality among cancer survivors DOI:10.3389/fimmu.2025.1541675 中文标题:癌症幸存者氧化平衡评分与全因死亡率和癌症特异性死亡率之间的关联 …...
python-修改图片背景色
在Python中,可以使用图像处理库(如OpenCV或Pillow)来修改图片的背景色。通常,修改背景色的流程包括以下步骤: 1、对图片进行分割,识别前景和背景。 2、对背景区域进行颜色替换。 下面是两种实现方法&#x…...
数据结构与算法--顺序表--单链表
一 顺序表 需要指向存储位置的基地址分配一段连续的内存用length记录实际的元素的个数,也即顺序表的长度,因为顺序表是允许删除和插入元素的不需要定义数组 1.1 普通结构体数组实现版本,实现白色的点以一定的步长移除画面,大量fo…...