Spring5学习笔记—Spring事务处理
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏: Spring专栏
✨特色专栏: MySQL学习
🥭本文内容:Spring5学习笔记—Spring事务处理
🖥️个人小站 :个人博客,欢迎大家访问
📚个人知识库: 知识库,欢迎大家访问
1. 什么是事务
事务是逻辑上的一组操作,要么都执行,要么都不执行。
相信大家应该都能背上面这句话了,下面我结合我们日常的真实开发来谈一谈。
我们系统的每个业务方法可能包括了多个原子性的数据库操作,比如下面的 save()
方法中就有两个原子性的数据库操作。这些原子性的数据库操作是有依赖的,它们要么都执行,要不就都不执行。
public void save() {personDao.save(student);personDetailDao.save(studentDetail);}
另外,需要格外注意的是:事务能否生效数据库引擎是否支持事务是关键。比如常用的 MySQL 数据库默认使用支持事务的 innodb
引擎。但是,如果把数据库引擎变为 myisam
,那么程序也就不再支持事务了
事务是保证业务操作完整性的一种数据库机制。事务的4特点: A C I D
1. A(Atomicity) 原子性
2. C(Consistency) 一致性
3. I(Isolation) 隔离性
4. D(durability) 持久性
- 原子性(
Atomicity
):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用; - 一致性(
Consistency
):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的; - 隔离性(
Isolation
):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的; - 持久性(
Durability
):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
🌈:只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!
2. Spring对事务的支持
Spring支持的两种事务管理
3.1 编程式事务管理
通过 TransactionTemplate
或者TransactionManager
手动管理事务,实际应用中很少使用。
使用TransactionTemplate
进行编程式事务管理的示例代码如下:
@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {try {// .... 业务代码} catch (Exception e){//回滚transactionStatus.setRollbackOnly();}}});
}
使用 TransactionManager
进行编程式事务管理的示例代码如下:
@Autowired
private PlatformTransactionManager transactionManager;public void testTransaction() {TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// .... 业务代码transactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);}
}
3.2 声明式事务管理
这一种方式实际上比较推荐的,实际是通过 AOP 实现(基于@Transactional
的全注解方式使用最多)。
使用 @Transactional
注解进行事务管理的示例代码如下:
public class Test {@Transactional(propagation = Propagation.REQUIRED)public void method() {/** 做业务**/MethodOne mb = new MethodOne();MethodOne mc = new MethodOne();mb.bMethod();mc.cMethod();}
}
Spring主要通过以下三个接口对事务进行管理
PlatformTransactionManager
:(平台)事务管理器,Spring 事务策略的核心。TransactionDefinition
:事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。TransactionStatus
:事务运行状态。
我们可以把 PlatformTransactionManager
接口可以被看作是事务上层的管理者,而 TransactionDefinition
和 TransactionStatus
这两个接口可以看作是事务的描述。
PlatformTransactionManager
会根据 TransactionDefinition
的定义比如事务超时时间、隔离级别、传播行为等来进行事务管理 ,而 TransactionStatus
接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚等等。
1. PlatformTransactionManager
简称事务管理接口
PlatformTransactionManager
接口中定义了三个方法:
package org.springframework.transaction;import org.springframework.lang.Nullable;public interface PlatformTransactionManager {//获得事务TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;//提交事务void commit(TransactionStatus var1) throws TransactionException;//回滚事务void rollback(TransactionStatus var1) throws TransactionException;
}
2. TransactionDefinition
简称事务属性
事务管理器接口 PlatformTransactionManager
通过 getTransaction(TransactionDefinition definition)
方法来得到一个事务,这个方法里面的参数是 TransactionDefinition
类 ,这个类就定义了一些基本的事务属性。
什么是事务属性呢? 事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。
事务属性包含了 5 个方面:
- 隔离级别
- 传播行为
- 回滚规则
- 是否只读
- 事务超时
TransactionDefinition
接口中定义了 5 个方法以及一些表示事务属性的常量比如隔离级别、传播行为等等。
package org.springframework.transaction;import org.springframework.lang.Nullable;public interface TransactionDefinition {int PROPAGATION_REQUIRED = 0;int PROPAGATION_SUPPORTS = 1;int PROPAGATION_MANDATORY = 2;int PROPAGATION_REQUIRES_NEW = 3;int PROPAGATION_NOT_SUPPORTED = 4;int PROPAGATION_NEVER = 5;int PROPAGATION_NESTED = 6;int ISOLATION_DEFAULT = -1;int ISOLATION_READ_UNCOMMITTED = 1;int ISOLATION_READ_COMMITTED = 2;int ISOLATION_REPEATABLE_READ = 4;int ISOLATION_SERIALIZABLE = 8;int TIMEOUT_DEFAULT = -1;// 返回事务的传播行为,默认值为 REQUIRED。int getPropagationBehavior();//返回事务的隔离级别,默认值是 DEFAULTint getIsolationLevel();// 返回事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。int getTimeout();// 返回是否为只读事务,默认值为 falseboolean isReadOnly();@NullableString getName();
}
3. TransactionStatus
简称事务状态
TransactionStatus
接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息。
PlatformTransactionManager.getTransaction(…)
方法返回一个 TransactionStatus
对象。
TransactionStatus 接口内容如下:
public interface TransactionStatus{boolean isNewTransaction(); // 是否是新的事务boolean hasSavepoint(); // 是否有恢复点void setRollbackOnly(); // 设置为只回滚boolean isRollbackOnly(); // 是否为只回滚boolean isCompleted; // 是否已完成
}
Spring对事务的支持
⚠️ 再提醒一次:你的程序是否支持事务首先取决于数据库 ,比如使用 MySQL 的话,如果你选择的是 innodb 引擎,那么恭喜你,是可以支持事务的。但是,如果你的 MySQL 数据库使用的是 myisam 引擎的话,那不好意思,从根上就是不支持事务的。
MySQL 怎么保证原子性的?
我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,在 MySQL 中,恢复机制是通过 回滚日志(undo log) 实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚之前未完成的事务。
Spring对事务控制
JDBC:
Connection.setAutoCommit(false);
Connection.commit();
Connection.rollback();
Mybatis:
Mybatis自动开启事务 sqlSession(Connection).commit();
sqlSession(Connection).rollback();结论:控制事务的底层 都是Connection对象完成的。
3. Spring控制事务的开发步骤:
Spring是通过AOP的方式进行事务的开发、
3.1 目标对象
public class XXXUserServiceImpl{private xxxDAO xxxDAOset get1. 原始对象 ---》 原始方法 ---》核心功能 (业务处理+DAO调用)2. DAO作为Service的成员变量,依赖注入的方式进行赋值
}
3.2 额外功能
1. org.springframework.jdbc.datasource.DataSourceTransactionManager
2. 注入DataSource
1. MethodInterceptorpublic Object invoke(MethodInvocation invocation){//原理:try{Connection.setAutoCommit(false);Object ret = invocation.proceed();Connection.commit();}catch(Exception e){Connection.rollback();}return ret;}
2. @Aspect@Around
3.3 切入点
@Transactional
事务的额外功能加入给哪些业务方法。
- 类上:类中所有的方法都会加入事务
- 方法上:这个方法会加入事务
3.4 组装切面
1. 切入点
2. 额外功能<tx:annotation-driven transaction-manager=""/>
4. Spring控制事务的真实编码:
-
搭建开发环境:
<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.1.14.RELEASE</version> </dependency>
-
编码:
<!-- 原始对象 --> <bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/> </bean><!--DataSourceTransactionManager--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 需要Connection 而Connection又在dataSource里 --><property name="dataSource" ref="dataSource"/> </bean>@Transactional public class UserServiceImpl implements UserService {private UserDAO userDAO; <!-- 告诉Spring开启基于注解的事务管理 --> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
-
细节:
<tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="true"/> 进行动态代理底层实现的切换 proxy-target-class默认 false JDKtrue Cglib
5. Spring的事务属性
事务属性简称 Transaction Attribute
5.1 什么是事务属性?
属性:描述物体特征的一系列值
性别 身高 体重 …
事务属性:描述事务特征的一系列值
- 隔离属性
- 传播属性
- 只读属性
- 超时属性
- 异常属性
5.2 如何添加事务属性
@Transactional(isloation=,propagation=,readOnly=,timeout=,rollbackFor=,noRollbackFor=,)
5.3 事务属性详解
1. 隔离属性 (ISOLATION)
-
隔离属性的概念
概念:他描述了事务解决并发问题的特征 1. 什么是并发多个事务(用户)在同一时间,访问操作了相同的数据同一时间:0.000几秒 微小前 微小后 2. 并发会产生那些问题1. 脏读2. 不可重复读3. 幻影读 3. 并发问题如何解决通过隔离属性解决,隔离属性中设置不同的值,解决并发处理过程中的问题。
-
事务并发会产生的问题
-
脏读
一个事务,读取了另一个事务中没有提交的数据。会在本事务中产生数据不一致的问题
解决方案 @Transactional(isolation=Isolation.READ_COMMITTED)
-
-
不可重复读
一个事务中,多次读取相同的数据,但是读取结果不一样。会在本事务中产生数据不一致的问题
注意:1 不是脏读 2 一个事务中
解决方案 @Transactional(isolation=Isolation.REPEATABLE_READ)
本质: 一把行锁-
幻影读
一个事务中,多次对整表进行查询统计,但是结果不一样,会在本事务中产生数据不一致的问题
解决方案 @Transactional(isolation=Isolation.SERIALIZABLE)
本质:表锁 -
总结
并发安全: SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED
运行效率: READ_COMMITTED > REPEATABLE_READ > SERIALIZABLE
-
-
数据库对于隔离属性的支持
隔离属性值 MySQL Oracle ISOLATION_READ_COMMITTED ✅ ✅ IOSLATION_REPEATABLE_READ ✅ ❎ ISOLATION_SERIALIZABLE ✅ ✅ Oracle不支持REPEATABLE_READ值 如何解决不可重复读?
采用的是多版本比对的方式 解决不可重复读的问题 -
默认隔离属性
ISOLATION_DEFAULT:会调用不同数据库所设置的默认隔离属性
MySQL : REPEATABLE_READ
Oracle: READ_COMMITTED -
查看数据库默认隔离属性
-
MySQL
select @@tx_isolation;
-
Oracle
SELECT s.sid, s.serial#,CASE BITAND(t.flag, POWER(2, 28))WHEN 0 THEN 'READ COMMITTED'ELSE 'SERIALIZABLE'END AS isolation_levelFROM v$transaction t JOIN v$session s ON t.addr = s.taddrAND s.sid = sys_context('USERENV', 'SID');
-
-
隔离属性在实战中的建议
推荐使用Spring指定的ISOLATION_DEFAULT
- MySQL repeatable_read
- Oracle read_commited
未来实战中,并发访问情况,很少
如果真遇到并发问题,乐观锁
Hibernate(JPA) Version
MyBatis 通过拦截器自定义开发
2. 传播属性(PROPAGATION)
-
传播属性的概念:
概念:他描述了事务解决嵌套问题的特征
什么叫做事务的嵌套:他指的是一个大的事务中,包含了若干个小的事务
问题:大事务中融入了很多小的事务,他们彼此影响,最终就会导致外部大的事务,丧失了事务的原子性
-
传播属性的值极其用法:
传播属性的值 外部不存在事务 外部存在事务 用法 备注 REQUIRED 开启新的事务 融合到外部事务中 @Transactional(propagation = Propagation.REQUIRED) 增删改方法 SUPPORTS 不开启事务 融合到外部事务中 @Transactional(propagation = Propagation.SUPPORTS) 查询方法 REQUIRES_NEW 开启新的事务 挂起外部事务,创建新的事务 @Transactional(propagation = Propagation.REQUIRES_NEW) 日志记录方法中 NOT_SUPPORTED 不开启事务 挂起外部事务 @Transactional(propagation = Propagation.NOT_SUPPORTED) 及其不常用 NEVER 不开启事务 抛出异常 @Transactional(propagation = Propagation.NEVER) 及其不常用 MANDATORY 抛出异常 融合到外部事务中 @Transactional(propagation = Propagation.MANDATORY) 及其不常用 -
默认传播属性:
Propagation.REQUIRED
-
推荐传播属性的使用方式
增删改 方法:直接使用默认值REQUIRED
查询 操作:显示指定传播属性的值为SUPPORTS
3. 只读属性(readOnly)
针对于只进行查询操作的业务方法,可以加入只读属性,提供运行效率
默认值:false
4. 超时属性(timeout)
指定了事务等待的最长时间
- 为什么事务进行等待?
当前事务访问数据时,有可能访问的数据被别的事务进行加锁的处理,那么此时本事务就必须进行等待。- 等待时间 秒
- 如何应用 @Transactional(timeout=2)
- 超时属性的默认值 -1
最终由对应的数据库来指定
5. 异常属性
Spring事务处理过程中
默认 对于RuntimeException及其子类 采用的是回滚的策略
默认 对于Exception及其子类 采用的是提交的策略rollbackFor = {java.lang.Exception,xxx,xxx}
noRollbackFor = {java.lang.RuntimeException,xxx,xx}@Transactional(rollbackFor = {java.lang.Exception.class},noRollbackFor = {java.lang.RuntimeException.class})
建议:实战中使用RuntimeExceptin及其子类 使用事务异常属性的默认值
5.4 事务属性常见配置总结
- 隔离属性 默认值
- 传播属性 Required(默认值) 增删改 Supports 查询操作
- 只读属性 readOnly false 增删改 true 查询操作
- 超时属性 默认值 -1
- 异常属性 默认值
增删改操作 @Transactional
查询操作 @Transactional(propagation=Propagation.SUPPORTS,readOnly=true)
5.5 基于标签的事务配置方式(事务开发的第二种形式)
-
基于注解 @Transaction的事务配置回顾
<bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/> </bean><!--DataSourceTransactionManager--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/> </bean>@Transactional(isolation=,propagation=,...) public class UserServiceImpl implements UserService {private UserDAO userDAO;<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
-
基于标签的事务配置:
<bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/> </bean><!--DataSourceTransactionManager--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/> </bean><!-- 事务属性 --> <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager"><tx:attributes><tx:method name="register" isoloation="",propagation=""></tx:method><tx:method name="login" .....></tx:method>等效于 @Transactional(isolation=,propagation=,)public void register(){}</tx:attributes> </tx:advice><aop:config><aop:pointcut id="pc" expression="execution(* com.baizhiedu.service.UserServiceImpl.register(..))"></aop:pointcut><aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor> </aop:config>
-
基于标签的事务配置在实战中的应用方式
<bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/> </bean><!--DataSourceTransactionManager--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/> </bean>编程时候 service中负责进行增删改操作的方法 都以modify开头查询操作 命名无所谓 <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager"><tx:attributes><tx:method name="register"></tx:method><tx:method name="modify*"></tx:method><tx:method name="*" propagation="SUPPORTS" read-only="true"></tx:method></tx:attributes> </tx:advice>应用的过程中,service放置到service包中 <aop:config><aop:pointcut id="pc" expression="execution(* com.baizhiedu.service..*.*(..))"></aop:pointcut><aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor> </aop:config>查询操作 命名无所谓 <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager"><tx:attributes><tx:method name="register"></tx:method><tx:method name="modify*"></tx:method><tx:method name="*" propagation="SUPPORTS" read-only="true"></tx:method></tx:attributes> </tx:advice>应用的过程中,service放置到service包中 <aop:config><aop:pointcut id="pc" expression="execution(* com.baizhiedu.service..*.*(..))"></aop:pointcut><aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor> </aop:config>
相关文章:

Spring5学习笔记—Spring事务处理
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Spring专栏 ✨特色专栏: M…...

如何增长LLM推理token,从直觉到数学
背景: 最近大模型输入上文长度增长技术点的研究很火。为何要增长token长度,为何大家如此热衷于增长输入token的长度呢?其实你如果是大模型比价频繁的使用者,这个问题应该不难回答。增长了输入token的长度,那需要多次出入才能得到…...

《穷爸爸与富爸爸》时间是最宝贵的资产,只有它对所有人都是公平的
《穷爸爸与富爸爸》时间是最宝贵的资产,只有它对所有人都是公平的 罗伯特清崎,日裔美国人,投资家、教育家、企业家。 萧明 译 文章目录 《穷爸爸与富爸爸》时间是最宝贵的资产,只有它对所有人都是公平的[toc]摘录各阶层现金流图支…...

Git结合Gitee的企业开发模拟
本系列有两篇文章: 一是另外一篇《快速使用Git完整开发》,主要说明了关于Git工具的基础使用,包含三板斧(git add、git commit、git push)、Git基本配置、版本回退、分支管理、公钥与私钥、远端仓库和远端分支、忽略文…...

WEBGL(2):绘制单个点
代码如下: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…...

C# task多线程创建,暂停,继续,结束使用
1、多线程任务创建 private void button1_Click(object sender, EventArgs e) //创建线程{CancellationToken cancellationToken tokensource.Token;Task.Run(() > //模拟耗时任务{for (int i 0; i < 100; i){if (cancellationToken.IsCancellationRequested){return;…...

界面控件DevExpress WinForms(v23.2)下半年发展路线图
本文主要概述了官方在下半年(v23.2)中一些与DevExpress WinForms相关的开发计划,重点关注的领域将是可访问性支持和支持.NET 8。 DevExpress WinForms有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。同时能…...

vue实现按需加载的多种方式
1.import动态导入 const Home () > import( /* webpackChunkName: "Home" */ /views/Home.vue); 2.使用vue异步组件resolve 这种方式没有成功 //const 组件名 resolve > require([‘组件路径’],resolve) //(这种情况下一个组件生成一个js文件…...

el-switch组件在分页情况下的使用
1.需求: 系统使用者在点击发布状态的开关后,可以对应的发布或者取消发布试卷 2.前端代码: html代码(这里不贴其他表单项的代码了,直接贴el-Switch组件的代码): <!-- qwy: 使用Switch组件,设置发布状态,业务逻辑:在页面初始渲染的时候应该查询发布状态,以根据状…...

【100天精通python】Day49:python web编程_web框架,Flask的使用
目录 1 Web 框架 2 python 中常用的web框架 3 Flask 框架的使用 3.1 Flask框架安装 3.2 第一个Flask程序 3.3 路由 3.3.1 基本路由 3.3.2 动态路由 3.3.3 HTTP 方法 3.3.4 多个路由绑定到一个视图函数 3.3.5 访问URL 参数的路由 3.3.6 带默认值的动态路由 3.3.7 带…...

sql 查重以及删除重复
查重 select count(1),content from t_mall_longping group by content having count(1)>1 稳重删除重复(技术来源于 百度文心一言,好屌呀) CREATE TABLE tmp_duplicates ( hxid INT PRIMARY KEY );INSERT INTO tmp_duplicates SEL…...

Flux语言 -- InfluxDB笔记二
1. 基础概念理解 1.1 语序和MySQL不一样,像净水一样通过管道一层层过滤 1.2 不同版本FluxDB的语法也不太一样 2. 基本表达式 import "array" s 10 * 3 // 浮点型只能与浮点型进行运算 s1 9.0 / 3.0 s2 10.0 % 3.0 // 等于 1 s3 10.0 ^ 3.0 // 等于…...

18.Oauth2-微服务认证
1.Oauth2 OAuth 2.0授权框架支持第三方支持访问有限的HTTP服务,通过在资源所有者和HTTP服务之间进行一个批准交互来代表资源者去访问这些资源,或者通过允许第三方应用程序以自己的名义获取访问权限。 为了方便理解,可以想象OAuth2.0就是在用…...

vue和node使用websocket实现数据推送,实时聊天
需求:node做后端根据websocket,连接数据库,数据库的字段改变后,前端不用刷新页面也能更新到数据,前端也可以发送消息给后端,后端接受后把前端消息做处理再推送给前端展示 1.初始化node,生成pac…...

汽车电子笔记之:基于AUTOSAR的多核监控机制
目录 1、概述 2、系统监控的目标 2.1、任务的状态机 2.2、任务服务函数 2.3、任务周期性事件 2.4、时间监控的指标 2.5、时间监控的原理 2.6、CPU负载率监控原理 2.6.1、设计思路 2.6.2、监控方法的评价 3、基于WDGM模块热舞时序监控方法 3.1、活跃监督 3.2、截至时…...

GDB 源码分析 -- 断点源码解析
文章目录 一、断点简介1.1 硬件断点1.2 软件断点 二、断点源码分析2.1 断点相关结构体2.1.1 struct breakpoint2.1.2 struct bp_location 2.2 断点源码简介2.3 break设置断点2.4 enable break2.5 disable breakpoint2.6 delete breakpoint2.7 info break 命令源码解析 三、Linu…...

SpringMVC概述与简单使用
1.SpringMVC简介 SpringMVC也叫做Spring web mvc,是 Spring 框架的一部分,是在 Spring3.0 后发布的。 2.SpringMVC优点 1.基于 MVC 架构 基于 MVC 架构,功能分工明确。解耦合, 2.容易理解,上手快;使用简单。 就可以…...

传输层—UDP原理详解
目录 前言 1.netstat 2.pidof 3.UDP协议格式 4.UDP的特点 5.面向数据报 6.UDP的缓冲区 7.UDP使用注意事项 8.基于UDP的应用层协议 总结 前言 在之前的文章中为大家介绍了关于网络协议栈第一层就是应用层,包含套接字的使用,在应用层编码实现服务…...

CK-GW06-E03与汇川PLC的EtherNet/IP通信
准备阶段: CK-GWO6-E03网关POE交换机网线汇川PLC编程软件汇川AC801-0221-U0R0型号PLC 1.打开汇川PLC编程软件lnoProShop(V1.6.2)SP2 新建工程,选择对应的PLC型号,编程语言选择为“结构化文本(ST)语言”,然…...

UI界面自动化BagePage
常用basepage模块代码 # -*- coding: utf-8 -*- # Desc: UI自动化测试的一些基础浏览器操作方法# 第三方库导入 import time from logging import config import randomimport allure from selenium.webdriver.common.alert import Alert from selenium.webdriver.remote.webe…...

北京开发APP的费用明细
开发APP项目时,在功能确定后需要知道有哪些可能的费用,安排项目预算。北京开发APP的费用明细可能会包括以下几个部分,每个部分都会产生一些费用。今天和大家分享APP费用明细有哪些,希望对大家有所帮助。北京木奇移动技术有限公司&…...

2023年MySQL核心技术第一篇
目录 一 . 存储:一个完整的数据存储过程是怎样的? 1.1 数据存储过程 1.1.1 创建MySQl 数据库 1.1.1.1 为什么我们要先创建一个数据库,而不是直接创建数据表? 1.1.1.2基本操作部分 1.2 选择索引问题 二 . 字段:这么多的…...

通讯协议056——全网独有的OPC HDA知识一之接口(十一)IOPCHDA_Playback
本文简单介绍OPC HDA规范的IOPCHDA_Playback(可选)接口方法,更多通信资源请登录网信智汇(wangxinzhihui.com)。 此接口支持历史服务器的播放功能。这提供了从历史服务器获得初始数据集的能力,然后获得历史数据的持续更新。这与异…...

数学建模:数据的预处理
🔆 文章首发于我的个人博客:欢迎大佬们来逛逛 文章目录 数据预处理数据变换数据清洗缺失值处理异常值处理 数据预处理 数据变换 常见的数据变换的方式:通过某些简单的函数进行数据变换。 x ′ x 2 x ′ x x ′ log ( x ) ∇ f ( x k )…...

Linux土遁术之监测监测进程打开文件
分析问题过程中,追踪进程打开的文件可以在许多不同情况下有用,体现在以下几个方面: 故障排除和调试: 当程序出现问题、崩溃或异常行为时,追踪进程打开的文件可以帮助您找出问题的根本原因。这有助于快速定位错误&…...

css让多个盒子强制自动等宽
1.width: calc( 100 / n% ) 2.display:flex; flex:1;width:100px; 3.display:grid;grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); 但是其中某一个内容较长的时候 会破坏1:1:1的平衡 这个时候发现附件名字过长导致不等比例,通过查看阮一峰flex文…...

【高危】Apache Airflow Spark Provider 反序列化漏洞 (CVE-2023-40195)
zhi.oscs1024.com 漏洞类型反序列化发现时间2023-08-29漏洞等级高危MPS编号MPS-qkdx-17bcCVE编号CVE-2023-40195漏洞影响广度广 漏洞危害 OSCS 描述Apache Airflow Spark Provider是Apache Airflow项目的一个插件,用于在Airflow中管理和调度Apache Spar…...

树模型与集成学习:LightGBM
目录 树模型与集成学习 LightGBM 的贡献 LightGBM 的贡献:单边梯度抽样算法 LightGBM 的贡献:直方图算法 LightGBM 的贡献:互斥特征捆绑算法 LightGBM 的贡献:深度限制的 Leaf-wise 算法 树模型与集成学习 树模型是非常好的…...

PHP多语言代入电商平台api接口采集拼多多根据ID获取商品详情原数据示例
拼多多商品详情原数据API接口的作用是获取拼多多电商平台上某一商品的详细信息,包括商品的标题、价格、库存、图片、描述、包邮信息、销量、评价、优惠券等数据。通过该API接口可以获取到商品的原始数据,用于分析、筛选和展示商品信息。 pinduoduo.item…...

数据结构(Java实现)-二叉树(下)
获取二叉树的高度 检测值为value的元素是否存在(前序遍历) 层序遍历 判断一棵树是不是完全二叉树 获取节点的路径 二叉树的最近公共祖先...