当前位置: 首页 > news >正文

Spring-声明式事务

声明式事务

  • 一、简介
    • 1、准备工作
    • 2、测试
  • 二、声明式事务概念
    • 1、编程式事务
    • 2、声明式事务
    • 3、基于注解的声明式事务
      • 1.测试无事务情况
      • 2.加入事务
        • ①@Transactional注解标识的位置
        • ②事务属性:只读
        • ③事务属性:超时
        • ④事务属性:回滚策略
        • ⑤事务属性:事务隔离级别
        • ⑥事务属性:事务传播行为


一、简介

Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作

1、准备工作

①加入依赖

    <dependencies><!-- 基于Maven依赖传递性,导入spring-context依赖即可导入当前所需所有jar包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.1</version></dependency><!-- Spring 持久化层支持jar包 --><!-- Spring 在执行持久化层操作、与持久化层技术进行整合过程中,需要使用orm、jdbc、tx三个jar包 --><!-- 导入 orm 包就可以通过 Maven 的依赖传递性把其他两个也导入 --><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>5.3.1</version></dependency><!-- Spring 测试相关 --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.1</version></dependency><!-- junit测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><!-- 数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.31</version></dependency></dependencies>

②创建jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3309/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

在这里插入图片描述
③配置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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--    引入jdbc依赖--><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean><!-- 配置 JdbcTemplate用于test测试--><bean class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean>
</beans>

2、测试

①在测试类装配 JdbcTemplate

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-jdbc.xml")
public class JDBCTemplateTest {
@Autowired
private JdbcTemplate jdbcTemplate;
}

②测试增删改功能

@Test
//测试增删改功能
public void testUpdate(){
String sql = "insert into t_emp values(null,?,?,?)";
int result = jdbcTemplate.update(sql, "张三", 23, "男");
System.out.println(result);
}

③查询一条数据为实体类对象

@Test
//查询一条数据为一个实体类对象
public void testSelectEmpById(){
String sql = "select * from t_emp where id = ?";
Emp emp = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>
(Emp.class), 1);
System.out.println(emp);
}

二、声明式事务概念

1、编程式事务

事务功能的相关操作全部通过自己编写代码来实现:

Connection conn = ...;try {
// 开启事务:关闭事务的自动提交conn.setAutoCommit(false);
// 核心操作
// 提交事务conn.commit();}catch(Exception e){
// 回滚事务conn.rollBack();}finally{// 释放数据库连接conn.close();}

编程式的实现方式存在缺陷:
细节没有被屏蔽:具体操作过程中,所有细节都需要程序员自己来完成,比较繁琐。
代码复用性不高:如果没有有效抽取出来,每次实现功能都需要自己编写代码,代码就没有得到复
用。

2、声明式事务

既然事务控制的代码有规律可循,代码的结构基本是确定的,所以框架就可以将固定模式的代码抽取出来,进行相关的封装。
封装起来后,我们只需要在配置文件中进行简单的配置即可完成操作。

  • 好处1:提高开发效率
  • 好处2:消除了冗余的代码
  • 好处3:框架会综合考虑相关领域中在实际开发环境下有可能遇到的各种问题,进行了健壮性、性
    能等各个方面的优化
    所以,我们可以总结下面两个概念:
  • 编程式:自己写代码实现功能
  • 声明式:通过配置让框架实现功能

3、基于注解的声明式事务

①加入依赖
准备工作已加(同简介中的准备工作)
②创建jdbc.properties
准备工作 已加(同简介中的准备工作)
③配置Spring的配置文件
准备工作 已加(同简介中的准备工作)
④创建表

CREATE TABLE `t_book` (
`book_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`book_name` varchar(20) DEFAULT NULL COMMENT '图书名称',
`price` int(11) DEFAULT NULL COMMENT '价格',
`stock` int(10) unsigned DEFAULT NULL COMMENT '库存(无符号)',
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into `t_book`(`book_id`,`book_name`,`price`,`stock`) values (1,'斗破苍
穹',80,100),(2,'斗罗大陆',50,100);
CREATE TABLE `t_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` varchar(20) DEFAULT NULL COMMENT '用户名',
`balance` int(10) unsigned DEFAULT NULL COMMENT '余额(无符号)',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
insert into `t_user`(`user_id`,`username`,`balance`) values (1,'admin',50);

⑤创建组件
创建BookController:

@Controller
public class BookController {
@Autowired
private BookService bookService;
public void buyBook(Integer bookId, Integer userId){
bookService.buyBook(bookId, userId);
}
}

创建接口BookService:

public interface BookService {/*** 买书* @param userId* @param bookId*/void buyBook(Integer userId, Integer bookId);
}

创建实现类BookServiceImpl:

@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Override/*** Transactional参数含义:* readOnly:只读* timeout:超时时间,超过设定的时间强制回滚*/@Transactional(//readOnly = true//timeout = 3//noRollbackFor = ArithmeticException.class//noRollbackForClassName = "java.lang.ArithmeticException"//isolation = Isolation.DEFAULTpropagation = Propagation.REQUIRES_NEW)public void buyBook(Integer userId, Integer bookId) {//SECONDS:秒 MINUTES:分钟 DAYS:天 HOURS:小时try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}//查询图书的价格Integer price = bookDao.getPriceByBookId(bookId);//更新图书的库存bookDao.updateStock(bookId);//更新用户的余额bookDao.updateBalance(userId, price);//System.out.println(1/0);}
}

创建接口BookDao:

public interface BookDao {/*** 根据图书的id查询图书的价格* @param bookId* @return*/Integer getPriceByBookId(Integer bookId);/*** 更新图书的库存* @param bookId*/void updateStock(Integer bookId);/*** 更新用户的余额* @param userId* @param price*/void updateBalance(Integer userId, Integer price);
}

创建实现类BookDaoImpl:

@Repository
public class BookDaoImpl implements BookDao {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic Integer getPriceByBookId(Integer bookId) {String sql = "select price from t_book where book_id = ?";return jdbcTemplate.queryForObject(sql, Integer.class, bookId);}@Overridepublic void updateStock(Integer bookId) {String sql = "update t_book set stock = stock - 1 where book_id = ?";jdbcTemplate.update(sql, bookId);}@Overridepublic void updateBalance(Integer userId, Integer price) {String sql = "update t_user set balance = balance - ? where user_id = ?";jdbcTemplate.update(sql, price, userId);}
}

1.测试无事务情况

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:tx-annotation.xml")
public class TxByAnnotationTest {@Autowiredprivate BookController bookController;@Testpublic void testBuyBook(){bookController.buyBook(1, 1);//bookController.checkout(1, new Integer[]{1,2});}}

2.加入事务

在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:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--    扫描组件--><context:component-scan base-package="org.example.spring"></context:component-scan>
<!--        导入外部组件--><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--    配置数据库--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean>
<!--    配置测试数据库的bean--><bean class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean>
<!--    配置事务管理器--><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean>
<!--    开启事务注解--><tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

注意:导入的名称空间需要 tx 结尾的那个。
在这里插入图片描述
②添加事务注解
因为service层表示业务逻辑层,一个方法表示一个完成的功能,因此处理事务一般在service层处理
在BookServiceImpl的buybook()添加注解@Transactional
③观察结果
由于使用了Spring的声明式事务,更新库存和更新余额都没有执行

①@Transactional注解标识的位置

@Transactional标识在方法上,只会影响该方法
@Transactional标识的类上,会影响类中所有的方法

②事务属性:只读

①介绍
对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。这
样数据库就能够针对查询操作来进行优化。
②使用方式

@Transactional(readOnly = true)
public void buyBook(Integer bookId, Integer userId) {
//查询图书的价格
Integer price = bookDao.getPriceByBookId(bookId);
//更新图书的库存
bookDao.updateStock(bookId);
//更新用户的余额
bookDao.updateBalance(userId, price);
//System.out.println(1/0);
}

③注意
对增删改操作设置只读会抛出下面异常:
Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification
are not allowed

③事务属性:超时

①介绍
事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。而长时间占用资源,大概率是因为程序运行出现了问题(可能是Java程序或MySQL数据库或网络连接等等)。
此时这个很可能出问题的程序应该被回滚,撤销它已做的操作,事务结束,把资源让出来,让其他正常程序可以执行。
概括来说就是一句话:超时回滚,释放资源。
②使用方式

@Transactional(timeout = 3)
public void buyBook(Integer bookId, Integer userId) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//查询图书的价格
Integer price = bookDao.getPriceByBookId(bookId);
//更新图书的库存
bookDao.updateStock(bookId);
//更新用户的余额
bookDao.updateBalance(userId, price);
//System.out.println(1/0);
}

③观察结果
执行过程中抛出异常:
org.springframework.transaction.TransactionTimedOutException: Transaction timed out:

④事务属性:回滚策略

①介绍
声明式事务默认只针对运行时异常回滚,编译时异常不回滚。
可以通过@Transactional中相关属性设置回滚策略

  • rollbackFor属性:需要设置一个Class类型的对象(回滚)
    举例:
 @Transactional(rollbackFor = CustomException.class) 

通过将rollbackFor属性设置为CustomException.class,告诉Spring只有当CustomException异常发生时才回滚事务。

  • rollbackForClassName属性:需要设置一个字符串类型的全类名(回滚)
    举例:
@Service
@Transactional
public class UserService {@Transactional(rollbackForClassName = "java.lang.RuntimeException")public void saveUser(User user) {// 保存用户信息的代码throw new RuntimeException("保存用户信息失败");}
}

rollbackForClassName属性接受一个字符串类型的异常类名。当在事务执行期间抛出与指定异常类名匹配的异常时,事务将会回滚。如果抛出的异常不匹配,则事务不会回滚。
在上面的例子中,如果saveUser()方法抛出RuntimeException异常,事务将会回滚。
需要注意的是,rollbackForClassName属性接受异常类名的字符串表示,类名需要包含完整的包路径。另外,也可以通过rollbackFor属性来指定异常类的Class对象,实现相同的效果。

  • noRollbackFor属性:需要设置一个Class类型的对象(针对某个类不回滚)
  • noRollbackForClassName属性:需要设置一个字符串类型的全类名
⑤事务属性:事务隔离级别

①介绍
数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。
隔离级别一共有四种:

  • 读未提交:READ UNCOMMITTED
    允许Transaction01读取Transaction02未提交的修改。
  • 读已提交:READ COMMITTED、
    要求Transaction01只能读取Transaction02已提交的修改。
  • 可重复读:REPEATABLE READ
    确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。
  • 串行化:SERIALIZABLE
    确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。
    各个隔离级别解决并发问题的能力见下表:
隔离级别脏读不可重复读幻读
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
②使用方式
@Transactional(isolation = Isolation.DEFAULT)//使用数据库默认的隔离级别
@Transactional(isolation = Isolation.READ_UNCOMMITTED)//读未提交
@Transactional(isolation = Isolation.READ_COMMITTED)//读已提交
@Transactional(isolation = Isolation.REPEATABLE_READ)//可重复读
@Transactional(isolation = Isolation.SERIALIZABLE)//串行化
⑥事务属性:事务传播行为

①介绍
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中
运行,也可能开启一个新事务,并在自己的事务中运行。
②测试
创建接口CheckoutService:

public interface CheckoutService {
void checkout(Integer[] bookIds, Integer userId);
}

创建实现类CheckoutServiceImpl:

@Service
public class CheckoutServiceImpl implements CheckoutService {@Autowiredprivate BookService bookService;@Override@Transactional//一次购买多本图书public void checkout(Integer[] bookIds, Integer userId) {for (Integer bookId : bookIds) {bookService.buyBook(bookId, userId);}}
}

在BookController中添加方法:

@Autowired
private CheckoutService checkoutService;
public void checkout(Integer[] bookIds, Integer userId){
checkoutService.checkout(bookIds, userId);
}

在数据库中将用户的余额修改为100元
③观察结果
可以通过@Transactional中的propagation属性设置事务传播行为
修改BookServiceImpl中buyBook()上,注解@Transactional的propagation属性

@Transactional(propagation = Propagation.REQUIRED),默认情况,表示如果当前线程上有已经开
启的事务可用,那么就在这个事务中运行。经过观察,购买图书的方法buyBook()在checkout()中被调
用,checkout()上有事务注解,因此在此事务中执行。所购买的两本图书的价格为80和50,而用户的余额为100,因此在购买第二本图书时余额不足失败,导致整个checkout()回滚,即只要有一本书买不
了,就都买不了。

@Transactional(propagation = Propagation.REQUIRES_NEW),表示不管当前线程上是否有已经开启的事务,都要开启新事务。同样的场景,每次购买图书都是在buyBook()的事务中执行,因此第一本图书购买成功,事务结束,第二本图书购买失败,只在第二次的buyBook()中回滚,购买第一本图书不受影响,即能买几本就买几本。

相关文章:

Spring-声明式事务

声明式事务 一、简介1、准备工作2、测试 二、声明式事务概念1、编程式事务2、声明式事务3、基于注解的声明式事务1.测试无事务情况2.加入事务①Transactional注解标识的位置②事务属性&#xff1a;只读③事务属性&#xff1a;超时④事务属性&#xff1a;回滚策略⑤事务属性&…...

腾讯云轻量服务器地域选择教程,一篇文章就够了

腾讯云轻量应用服务器地域是指轻量服务器数据中心所在的地理位置&#xff0c;如上海、广州和北京等地域&#xff0c;如何选择地域&#xff1f;腾讯云百科txybk.com建议地域选择遵循就近原则&#xff0c;用户距离轻量服务器地域越近&#xff0c;网络延迟越低&#xff0c;速度就越…...

【斗罗二】王东升级三环,戴华斌挑衅,雨浩单手接鼎订下赌约

【侵权联系删除】【文/郑尔巴金】 深度爆料&#xff0c;《绝世唐门》第20集&#xff0c;一场瞩目的战斗即将爆发。王冬&#xff0c;这位一年级的强攻系班长&#xff0c;将与戴华斌进行一场激烈的较量。王冬拥有三大武魂&#xff0c;其中最为人们所熟知的是那光明女神蝶&#x…...

洛谷 B2135:单词替换

【题目来源】https://www.luogu.com.cn/problem/B2135【题目描述】 输入一个字符串&#xff0c;以回车结束&#xff08;字符串长度 ≤200&#xff09;。该字符串由若干个单词组成&#xff0c;单词之间用一个空格隔开&#xff0c;所有单词区分大小写。现需要将其中的某个单词替换…...

IDEA中application.properties文件中文乱码

现象&#xff1a; 原因&#xff1a; 项目编码格式与IDEA编码格式不一致导致的 解决办法&#xff1a; 在File->Settings->Editor->File Encodings选项中&#xff0c;将Global Encoding,Project Encoding,Default encoding for properties files这三个选项置为一致&a…...

Rust 模块系统

文章目录 模块系统crate包cargo 创建库库的使用 模块系统 Rust的{模块系统|the module system}&#xff0c;包括&#xff1a; * 包&#xff08;Packages&#xff09;&#xff1a; Cargo 的一个功能&#xff0c;它允许你构建、测试和分享 crate。 * Crates &#xff1a;一个模…...

面向服务架构-架构师(六十四)

SOA概述和发展、参考架构、协议和规范、标准和原则、设计模式、构件和实施。 SOA概述和发展 服务指系统对外提供的功能&#xff0c;SOA是一种应用框架。 微服务去掉了ESB企业服务总线&#xff0c;SOA集中式&#xff0c;SOA和微服务的区别&#xff1a; 微服务更加精细。服务…...

Linux之系统编程

1.yum 1.yum list可以出现所有可下载的程序 辅助grep进行查找 2.yum install可以下载并安装 3.yum remove可以卸载程序 不同的商业操作系统内核都是一样的&#xff0c;主要是配套社区不一样。 开源组织&#xff0c;各大公司&#xff0c;既得利益者。 同上 基础软件源可以保证…...

信道数据传输速率、信号传播速度——参考《天勤计算机网络》

一、缘起题目 二、解析 三、总结 信道数据传输速率和信号传播速度是两个不同的概念。 3.1 信道数据传输速率&#xff08;Channel Data Transfer Rate&#xff09; 指的是在通信系统中&#xff0c;通过信道传输的数据量&#xff0c;通常以 比特率&#xff08;bits per second…...

微信小程序vue+uniapp旅游景点门票预订系统 名胜风景推荐系统

与此同时越来越多的旅游公司建立了自己的基于微信小程序的名胜风景推荐平台&#xff0c;管理员通过网站可以添加用户、景点分类、景点信息、在线预订、最新推荐&#xff0c;用户可以对景点信息进行在线预订&#xff0c;以及开展电子商务等。互联网的世界里蕴藏无限生机&#xf…...

每日一题之二分查找(一)

每日一题之二分查找&#xff08;一&#xff09; 1.题目&#xff08;搜索插入位置&#xff09; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间…...

Redisson的看门狗策略——保障Redis数据安全与稳定的机制

前言 自定义redis分布式锁无法自动续期&#xff0c;比如&#xff0c;一个锁设置了1分钟超时释放&#xff0c;如果拿到这个锁的线程在一分钟内没有执行完毕&#xff0c;那么这个锁就会被其他线程拿到&#xff0c;可能会导致严重的线上问题&#xff0c;在秒杀场景下&#xff0c;…...

2.2 消元法的概念

一、消元法介绍 消元法&#xff08;elimination&#xff09;是一个求解线性方程组的系统性方法。下面是使用消元法求解一个 2 2 2\times2 22 线性方程组的例子。消元之前&#xff0c;两个方程都有 x x x 和 y y y&#xff0c;消元后&#xff0c;第一个未知数 x x x 将从第…...

删除有序数组中的重复项

目录 题目&#xff1a; 示例&#xff1a; 题目分析&#xff1a; 解题思路&#xff1a; 题目&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的…...

【数据库】

文章目录 1. 聚合函数练习&#xff1a; 2. 子查询 1. 聚合函数 where中过滤条件中不能写聚合函数&#xff0c;有聚合函数需要写到Having中 方式一效率高&#xff1a; Select执行流程 练习&#xff1a; 2. 第七题&#xff1a;count(*)有问题&#xff0c;原因是左外连接后…...

高级深入--day38

阳光热线问政平台 http://wz.sun0769.com/index.php/question/questionType?type4 爬取投诉帖子的编号、帖子的url、帖子的标题&#xff0c;和帖子里的内容。 items.py import scrapyclass DongguanItem(scrapy.Item):# 每个帖子的标题title scrapy.Field()# 每个帖子的编…...

基于springboot,vue校园社团管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plus 本系…...

广州华锐互动:VR虚拟现实物理学习平台,开启数字化教学新格局

随着虚拟现实(VR)技术的不断发展&#xff0c;越来越多的领域开始应用这一技术。广州华锐互动开发的VR虚拟现实物理学习平台就得到了广泛应用&#xff0c;平台涉及力学、光学、热学等初中物理知识&#xff0c;还包含了物理名人、实验器具、物理现象的还原和学习&#xff0c;相比…...

【tio-websocket】8、T-IO对半包和粘包的处理

介绍 t-io对数据的解码是在DecodeRunnable中完成的,一个TCP连接对应一个DecodeRunnable半包粘包的处理也都在DecodeRunnable中完成的关于DecodeRunnable 先贴上 DecodeRunnable 的源代码: import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import j…...

【Linux】安装与配置虚拟机及虚拟机服务器坏境配置与连接

目录 操作系统介绍 什么是操作系统 常见操作系统 UNIX操作系统 linux操作系统 mac操作系统 嵌入式操作系统 个人版本和服务器版本的区别 安装VMWare虚拟机 VMWare虚拟网卡 ​编辑 配置虚拟网络编辑器 ​编辑 安装配置Windows Server 2012 R2 安装Windows Server 2…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...