Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)

news/2024/5/15 23:33:58/文章来源:https://blog.csdn.net/m0_58761900/article/details/129032525

文章目录

  • 1. 事务的定义
  • 2. Spring 中事务的实现
    • 2.1 MySQL 中使用事务
    • 2.2 Spring 中编程式事务的实现
    • 2.3 Spring 中声明式事务
      • 2.3.1 声明式事务的实现 @Transactional
      • 2.3.2 @Transactional 作用域
      • 2.3.3@Transactional 参数设置
      • 2.3.4 @Transactional 异常情况
      • 2.3.5 @Transactional 工作原理
  • 3. 事务隔离级别
    • 3.1 事务特性
    • 3.2 Spring 中设置事务隔离级别
  • 4. Spring 事务传播机制
    • 4.1 事务传播机制是什么
    • 4.2 为什么需要事务传播机制
    • 4.3 事务传播机制有哪些
    • 4.4 Spring 事务传播机制使用
      • 4.4.1 支持当前事务(REQUIRED 默认)
      • 4.4.2 不支持当前事务(REQUIRES_NEW)
      • 4.4.3 不支持当前事务(NOT_SUPPORTED)
      • 4.4.4 NESTED 嵌套事务
      • 4.4.5 嵌套事务和加入事务的区别

本篇重点总结:

  1. 在 Spring 项目中使用事务,有两种方式:编程式手动操作和声明式自动提交,声明式自动提交使用最多,只需要在方法上添加注解 @Transactional
  2. 设置事务的隔离级别 @Transactional(isolation = Isolation.SERIALIZABLE),Spring 中的事务隔离级别有5种
  3. 设置事务的传播机制 @Transactional(propagation = Propagation.REQUIRED),Spring 中的事务传播级别有 7 种

1. 事务的定义

事务定义:将一组操作封装成一个执行单元(封装到一起),要么全部成功,要么全部失败

那么为什么要用事务呢

比如两个银行账户之间的转账操作:

  1. 第一步操作:A 账户 -100 元
  2. 第二步操作:B 账户 +100 元

如果没有事务。第一步执行成功了,第二步执行失败了,那么 A 账号就丢失了 100 元,而如果使用事务就可以解决这个问题,让这一组操作要么一起成功,要么一起失败


2. Spring 中事务的实现

Sping 中事务的操作用两种:

  1. 编程式事务(手写代码操作事务)
  2. 声明式事务(利用注解自动开启和提交事务)

2.1 MySQL 中使用事务

MySQL 中事务有 3 个重要的操作:开启事务、提交事务、回滚事务,它们对应的操作命令如下

-- 开启事务
start transaction;-- 业务执⾏
-- 提交事务
commit;
-- 回滚事务
rollback;

2.2 Spring 中编程式事务的实现

Spring 中手动操作事务和 MySQL操作事务类似,也是有 3 个重要操作

  1. 开启事务(获取事务)
  2. 提交事务
  3. 回滚事务

Spring Boot 内置了两个对象,DataSourceTransactionManager (事务管理器)用来获取事务(开启事务)、提交或回滚事务的,而 TransactionDefinition 是事务的属性,在获取事务的时候需要将 TransactionDefinition 传递进去从而获得一个事务 TransactionStatus 对象

@RestController
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate DataSourceTransactionManager transactionManager;@Autowiredprivate TransactionDefinition transactionDefinition;// 在此方法中使用编程式的事物@RequestMapping("/add")public int add(UserInfo userInfo) {// 非空效验【验证用户名和密码不为空】if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}// 开启事务(获取事务)TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);int result = userService.add(userInfo);System.out.println("add 受影响的行数:" + result);// 提交事务transactionManager.commit(transactionStatus);
//        // 回滚事务
//        transactionManager.rollback(transactionStatus);return result;}
}

运行程序分别查看提交事务和回滚事务的效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CDdDwGaw-1676374722301)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676287772298.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3cm5944-1676374722302)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676287783586.png)]


2.3 Spring 中声明式事务

2.3.1 声明式事务的实现 @Transactional

声明式事务的实现,只需要在方法上添加 @Transactional 注解就可以实现,无序手动开启事务和提交事务,进入方法时自动开启事务,方法执行完全会自动提交事务,如果中途发生了没有处理的异常会自动回滚事务

// 在此方法中使用声明式的事物
// 在进入方法之前,自动开启事务,在方法之前完后,自动提交事务,如果出现异常,则自动回滚事务
@Transactional
@RequestMapping("/add2")
public int add2(UserInfo userInfo) {if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int result = userService.add(userInfo);System.out.println("add2 受影响的行数:" + result);int num = 10/0;return result;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S21gpiHu-1676374722303)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676288819713.png)]

去除异常的那行代码重新运行程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Vx76KGj-1676374722303)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676289003919.png)]


2.3.2 @Transactional 作用域

@Transactional 可以用来修饰方法或类:

  • 修饰方法时,只能应用到 public 方法上,否则不生效
  • 修饰类时,说明该注解对该类中所有的 public 方法都生效

2.3.3@Transactional 参数设置

参数作用
value当你配置多个事务管理器时,可以使用该属性指定选择用哪个事务管理器
transactionManager同上
propagation事务的传播行为,默认值为 Propagation.REQUIRED
isolation事务的隔离级别,默认值为 Isolation.DEFAULT
timeout事务的超时时间,默认值为-1,如果超过该时间限制但事务还没完成,则自动回滚事务
readOnly指定事务是否为只读事务,默认值为 false,为了忽略那些不需要事务的方法,比如读取数据可以设置 read-only 为 true
rolibackFor用于指定能够触发事务回滚的异常类型,可以指定多个异常类型
rolibackForClassName同上
noRolibackFor抛出指定的异常类型,不回滚事务,也可以指定多个异常类型
noRollbackForClassName同上

设置事务的隔离级别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ibpM3tny-1676374722304)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676292506013.png)]

设置事务的超时时间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NIxWwKWm-1676374722304)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676293014348.png)]


2.3.4 @Transactional 异常情况

@Transactional 在异常被捕获的情况下,不会进⾏事务⾃动回滚

@Transactional
@RequestMapping("/add3")
public int add3(UserInfo userInfo) {if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int result = userService.add(userInfo);System.out.println("add2 受影响的行数:" + result);try {int num = 10/0;} catch (Exception e) {}return result;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ueCyvrWj-1676374722305)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676356422586.png)]

解决方法1:将异常重新抛出去

对于捕获的异常,事务是会⾃动回滚的,因此解决⽅案1就是将异常重新抛出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y0emxEE9-1676374722306)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676356654556.png)]

解决方法2:使用代码的方式手动回滚当前事务

手动回滚事务,在⽅法中使⽤ TransactionAspectSupport.currentTransactionStatus() 可以得到当前的事务,然后设置回滚方法 setRollbackOnly 就可以实现回滚了,具体实现代码

    @Transactional@RequestMapping("/add3")public int add3(UserInfo userInfo) {if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int result = userService.add(userInfo);System.out.println("add2 受影响的行数:" + result);try {int num = 10/0;} catch (Exception e) {//手动回滚事务TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}return result;}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X3KVRTil-1676374722306)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676356967349.png)]


2.3.5 @Transactional 工作原理

@Transactional 是基于 AOP 实现的,AOP 又是使用动态代理来实现的。如果目标对象实现了接口,默认情况下采用 JDK 的动态代理,如果目标对象没有实现接口,会使用 CGLIB 动态代理。@Transactional 在开始执行业务之前,通过代理先开启事务,在执行成功之后再提交事务,如果中途遇到异常,则回滚事务

@Transactional 实现思路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U53Wzj7E-1676374722307)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676358204440.png)]

@Transactional 具体执行细节

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2L3MlAy7-1676374722308)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676358241159.png)]


3. 事务隔离级别

3.1 事务特性

事务有四大特性(ACID),原子性、持久性、一致性和隔离性

  1. 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成。不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态
  2. 一致性(Consistency):在事务开始之前和事务事务结束之后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精准度、串联性以及后续数据库可以自发性地完成预定的工作
  3. 持久性(Isolation):事务处理结束后,对数据的修改就是永久的。即使系统故障也不会丢失
  4. 隔离性(Durability):数据库允许多个并发事务同时对其数据进行读写和修改的能力。隔离性可以防止多个事务并发执行时由交叉执行而导致数据的不一致。

这四个特性中,只有隔离性(隔离级别)是可以设置的


3.2 Spring 中设置事务隔离级别

为什么要设置事务的隔离级别

设置事务的隔离级别是用来保障多个并发事务执行更可控,更符合操作者预期的

这个可控表示的是,比如疫情的时候,有确诊、密接、次密接等针对不同的人群,采取不同的隔离级别,这种方式与事务的隔离级别类似,都是让某种行为操作变的 更可控事务的隔离级别就是为了防止,其他事务影响当前事务执行的一种策略

MySQL 事务隔离级别有 4 种

  1. 读未提交(READ UNCOMMITTED ):事务A读到了事务B没有提交的数据,然后过了一会事务B进行了回滚,此时**事务A的这个情况就叫脏读,读到的数据也叫脏数据,读未提交侧重于查询,**既然有了脏读,那么也肯定有不可重复读和幻读的问题
  2. 读已提交(READ COMMITTED):针对上面脏读的问题来解决的,事务A读到了事务B已经提交的数据,然后过了一会事务B将提交的数据进行修改了,此时事务A又读了一次B的数据,发现两次读到读到数据不一样,这个就叫不可重复读的问题,读已提交侧重的是修改,还是存在不可重复读和幻读的问题
  3. 可重复读(REPEATABLE READ) :针对的是上面不可重复读的问题,事务A此时查询数据发现表中只有一条数据,然后事务B又过来拆台了,事务B又插入了一条数据,事务A再次查询发现,哎!我出现幻觉了吗,刚刚不是只有一条数据么,现在咋又变成了两条数据了,是出现幻觉了吗,这个问题就叫 幻读,可重复读侧重的是添加和删除,只存在幻读的问题了
  4. 串行化(SERIALIZABLE):事务最高的隔离级别,解决了脏读、不可重复读、幻读的问题,但这个级别执行效率低
事务隔离级别脏读不可重复读幻读
读未提交(READ UNCOMMITTED)
读已提交(READ COMMITTED)
可重复读(REPEATABLE READ)
串行化(SERIALIZABLE)

Spring 中事务隔离级别有 5 种

多了一个默认事务隔离级别 DEFAULT 以连接的数据库事务隔离级别为准,如果连接的是 MySQL 那么默认就是 可重复读

注意事项:

  1. 当 Spring 中设置了事务隔离级别和连接的数据库(MySQL)事务隔离级别发送冲突的时候,以Spring为准
  2. Spring 中的事务隔离级别机制的实现是依靠连接数据库支持事务隔离级别为基础

Spring 中事务隔离级别可以通过 @Transactional 中的 isolation 属性进行设置


4. Spring 事务传播机制

4.1 事务传播机制是什么

Spring 事务传播机制:多个事务在相互调用时,事务是如何传递的

4.2 为什么需要事务传播机制

事务隔离级别是保证多个并发事务执⾏的可控性的(稳定性的),⽽事务传播机制是保证⼀个事务在多个调⽤⽅法间的可控性的(稳定性的)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nl69KKT9-1676374722309)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676361930104.png)]

4.3 事务传播机制有哪些

事务的传播机制有 7 种:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pvcupysn-1676374722309)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676362237124.png)]

  1. Propagation.REQUIRED:默认的事务传播级别,它表示如果当前存在事务,则加入事务;如果当前没有事务,则创建一个新的事务
  2. Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
  3. Propagation.MANDATORY;(mandatory 强制性)如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
  4. Propagation.REQUIRES_ENW:表示创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰
  5. Propagation.NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起
  6. Propagation.NEVER:以非事务方式运行,如果当前存在事务,则抛出异常
  7. Propagation.NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LNBCGXn4-1676374722310)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676364699386.png)]

4.4 Spring 事务传播机制使用

4.4.1 支持当前事务(REQUIRED 默认)

在mycnblog数据库中,先创建一个表

mysql> create table loginfo(-> id int primary key auto_increment,-> name varchar(250),-> `desc` text,-> createtime datetime default CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.04 sec)mysql> desc loginfo;
+------------+--------------+------+-----+-------------------+----------------+
| Field      | Type         | Null | Key | Default           | Extra          |
+------------+--------------+------+-----+-------------------+----------------+
| id         | int(11)      | NO   | PRI | NULL              | auto_increment |
| name       | varchar(250) | YES  |     | NULL              |                |
| desc       | text         | YES  |     | NULL              |                |
| createtime | datetime     | YES  |     | CURRENT_TIMESTAMP |                |
+------------+--------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)

以下代码实现中,先开启事务先成功插入一条用户数据,然后再执行日志报错,而在日志报错是发生了异常,观察 propagation = Propagation.REQUIRED 的执行结果

@RestController
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate LogService logService;@Transactional(propagation = Propagation.REQUIRED)@RequestMapping("/add4")public int add4(UserInfo userInfo) {if(userInfo == null || !StringUtils.hasLength(userInfo.getUsername())|| !StringUtils.hasLength(userInfo.getPassword())) {return 0;}int userResult = userService.add(userInfo);System.out.println("添加用户:" + userResult);LogInfo logInfo = new LogInfo();logInfo.setName("添加用户");logInfo.setDesc("添加用户结果:" + userResult);int logResult =  logService.add(logInfo);return userResult;}
}

在这里插入图片描述

执行结果:程序报错,数据库没有插⼊任何数据

执行流程

  1. UserService 中的保存⽅法正常执⾏完成。

  2. LogService 保存⽇志程序报错,因为使⽤的是 Controller 中的事务,所以整个事务回滚。

  3. 数据库中没有插⼊任何数据,也就是步骤 1 中的⽤户插⼊⽅法也回滚了。


4.4.2 不支持当前事务(REQUIRES_NEW)

UserController 类中的代码不变,将添加用户和添加日志的方法修改为 REQUIRES_NEW 不支持当前事务,重新创建事务

在这里插入图片描述
运行程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xRek64FZ-1676374722312)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676369232749.png)]


4.4.3 不支持当前事务(NOT_SUPPORTED)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNO5pVdC-1676374722312)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676372475953.png)]


4.4.4 NESTED 嵌套事务

方法调用流程:Controller/add ——》 用户添加方法(userservice) ——》 日志添加方法(logservice)

当日志添加方法出现异常之后,嵌套事务的执行结果是:

  1. 用户添加不受影响,添加用户成功
  2. 日志添加失败,因为发生异常回滚了事务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fGPQVmTM-1676374722312)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676371659498.png)]


4.4.5 嵌套事务和加入事务的区别

先看嵌套事务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JqyEXrxd-1676374722313)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676373164427.png)]

在 LogService 中进行事务的回滚操作

最终执行的效果就是,User 表成功添加数据,而 Log 表中没有添加数据。Log 中的事务已经回滚,但是嵌套事务不会回滚嵌套之前的事务,也就是说 嵌套事务可以实现部分事务回滚

加入事务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GnP7AlMP-1676374722313)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676373526005.png)]

最终程序的执行结果:用户表和日志表都没有添加任何数据,说明整个事务都回滚了。也就是说 REQUIRED 如果回滚就是回滚所有事务,不能实现部分事务的回滚

嵌套事务之所以能够实现部分事务的回滚,是因为事务中有一个保存点(相当于游戏存档),嵌套事务进入之后相当于新建一个保存点,而回滚时只回滚到当前保存点,因此之前的事务是不受影响的。

而 REQUIRED 是加入到当前事务中,并没有创建事务的保存点,因此出现了回滚就是整个事务的回滚

总结二者区别:

  • 整个事务如果全部执行成功,二者的结果是一样的
  • 如果事务执行到一半失败了,那么加入事务整个事务都会回滚;而嵌套事务会局部回滚,不会影响上一个方法中执行的结果

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

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

相关文章

一文读懂PaddleSpeech中英混合语音识别技术

语音识别技术能够让计算机理解人类的语音,从而支持多种语音交互的场景,如手机应用、人车协同、机器人对话、语音转写等。然而,在这些场景中,语音识别的输入并不总是单一的语言,有时会出现多语言混合的情况。例如&#…

ClickHouse进阶篇-多表连接物化视图

简介 在写这篇文章的时候doris 1.2 的物化视图只是支持单表建立物化视图,现在说下ClickHouse多表的物化视图。 前言 本文翻译自 Altinity 针对 ClickHouse 的系列技术文章。面向联机分析处理(OLAP)的开源分析引擎 ClickHouse,因…

全面了解 B 端产品设计 — 基础扫盲篇

在今天,互联网的影响力与作用与日俱增,除了我们日常生活领域的改变以外,对于商业领域的渗透也见效颇丰。 越来越多的企业开始使用数字化的解决方案来助力企业发展,包括日常管理、运营、统计等等。或者通过互联网的方式开发出新的业务形态,进行产业升级,如这几年风头正劲的…

ReentrantLock详说

目录 尝试加锁 如果加锁不成功 重点 尝试加锁 最外层lock方法 ReentrantLock.class public void lock() {sync.lock();} 进来发现是个抽象方法 abstract static class Sync extends AbstractQueuedSynchronizer abstract void lock(); 底下有两个实现类,一个…

Zookeeper3.5.7版本——Zookeeper的概述、工作机制、特点、数据结构及应用场景

目录一、Zookeeper的概述二、Zookeeper的工作机制三、Zookeeper的特点四、Zookeeper的数据结构五、Zookeeper的应用场景5.1、统一命名服务5.2、统一配置管理5.3、统一集群管理5.4、服务器动态上下线5.5、软负载均衡一、Zookeeper的概述 Zookeeper 是一个开源的分布式的&#x…

39万字完整版智能矿山项目建设整体解决方案

本资料来源网络,仅做知识分享,请勿商用。完整资料领取见文末,部分资料内容: 1.1 总体技术要求 1.1.1 核心业务架构 智能矿山业务架构是在统一的标准与规范及安全运维保障体系下,按分层设计模式,分为设备层、…

【基于机器学习的推荐系统项目实战-1】初识推荐系统

本文目录一、为什么我们需要推荐系统?二、推荐系统的发展阶段三、推荐系统模型四、通用推荐系统框架4.1 数据生产4.2 数据存储4.3 算法召回4.4 结果排序4.5 结果应用4.6 新浪微博的框架开源结构图五、推荐常用特征5.1 用户特征5.2 物品特征六、推荐常用算法七、结果…

【自动化测试】一位自动化测试工程师居然不会封装框架?神秘自动化测试框架......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 自动化测试框架 自…

山寨APP频出?安全工程师和黑灰产在较量

在山寨这个领域,没有人比黑灰产更懂模仿。 据安全从业者介绍,一般而言,对于成熟的山寨开发者来说,几天时间内就可以做出一套前端框架。服务器、源代码、域名、服务商这些内容的创建,通过网上租赁的方式就可以解决。 比…

小红书“复刻”微信,微信“内造”小红书

配图来自Canva可画 随着互联网增长红利逐渐见顶,各大互联网平台对流量的争夺变得愈发激烈。而为了寻找新的业务可能性,各家都在不遗余力地拓宽自身边界。在此背景下,目前最为“吸睛”和“吸金”的社交、电商、种草、短视频等领域&#xff0c…

Qt音视频开发19-vlc内核各种事件通知

一、前言 对于使用第三方的sdk库做开发,除了基本的操作函数接口外,还希望通过事件机制拿到消息通知,比如当前播放进度、音量值变化、静音变化、文件长度、播放结束等,有了这些才是完整的播放功能,在vlc中要拿到各种事…

【vulhub漏洞复现】CVE-2018-2894 Weblogic任意文件上传漏洞

一、漏洞详情影响版本weblogic 10.3.6.0、weblogic 12.1.3.0、weblogic 12.2.1.2、weblogic 12.2.1.3WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应…

快速吃透π型滤波电路-LC-RC滤波器

π型滤波器简介 π型滤波器包括两个电容器和一个电感器,它的输入和输出都呈低阻抗。π型滤波有RC和LC两种, 在输出电流不大的情况下用RC,R的取值不能太大,一般几个至几十欧姆,其优点是成本低。其缺点是电阻要消耗一些…

计算机组成原理4小时速成6:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线

计算机组成原理4小时速成6:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人&#xff0c…

操作系统——11.线程概念和多线程模型

这篇文章我们来讲一下操作系统中的线程概念和多线程模型 目录 1.概述 2.线程 2.1问题提出 2.2线程概念 2.3带来的变化 2.4线程的属性 2.5线程的实现方式 2.5.1用户级线程 2.5.2内核级线程 2.5.3相互组合 2.6多线程模型 2.6.1多对一模型 2.6.2一对一模型 2.6.3多…

linux代码库生成-make示例

1、add.c代码实现加法运算: int add(int a,int b) { return ab; } 2、头文件add.h #ifndef ADD_H #define ADD_H int add(int a,int b); #endif 3、CMakeLists.txt编写 cmake_minimum_required(VERSION 2.6) set(CMAKE_C_FLAGS -m32) project(test_add) include_dir…

骨传导耳机推荐,列举几款骨传导主流的耳机分享

随着科技的发展,耳机也发生了巨大的变化,从最初的传统入耳式耳机到骨传导耳机,越来越多的人开始使用这种听音乐的方式。它可以带给我们更好的体验。骨传导耳机顾名思义就是一种类似骨传导发声原理的无线耳机。这篇文章就是介绍目前市面上比较…

【快速理解和上手】逻辑回归logistic regression (无原理,只有公式化步骤)

逻辑回归 Logistic regression 目的:解决二分类问题 数学效果:根据数据(x⃗,y)(\vec{x}, y)(x,y) (其中y为0或1),拟合一条曲线,x轴表示特征,y轴表示一个概率,即这个输入 xxx 对应着…

《OpenGL宝典》--统一变量

统一变量 [layout (location 0)] uniform float f 1.0f;若设置layout,则不需要使用glGetUniformLocation来获取统一变量的位置 使用glUniform*传递值,glUniformMatrix*()设置矩阵统一变量。 glUseProgram(myShader); glUniform1f(0,45.2f);//0为loc…

香港双重牌照、准入安排和禁止事项等重要制度已明确 20多万字的《虚拟资产咨询文件》以证雄心

前不久,香港证监会就加密货币交易发布的《有关适用于获证券及期货事务监察委员会发牌的虚拟资产交易平台营运者的建议监管规定的咨询文件》(以下简称《咨询文件》),并如期就有关监管虚拟资产交易平台的建议展开咨询,以…