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注解标识的位置②事务属性:只读③事务属性:超时④事务属性:回滚策略⑤事务属性&…...
腾讯云轻量服务器地域选择教程,一篇文章就够了
腾讯云轻量应用服务器地域是指轻量服务器数据中心所在的地理位置,如上海、广州和北京等地域,如何选择地域?腾讯云百科txybk.com建议地域选择遵循就近原则,用户距离轻量服务器地域越近,网络延迟越低,速度就越…...
【斗罗二】王东升级三环,戴华斌挑衅,雨浩单手接鼎订下赌约
【侵权联系删除】【文/郑尔巴金】 深度爆料,《绝世唐门》第20集,一场瞩目的战斗即将爆发。王冬,这位一年级的强攻系班长,将与戴华斌进行一场激烈的较量。王冬拥有三大武魂,其中最为人们所熟知的是那光明女神蝶&#x…...
洛谷 B2135:单词替换
【题目来源】https://www.luogu.com.cn/problem/B2135【题目描述】 输入一个字符串,以回车结束(字符串长度 ≤200)。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换…...
IDEA中application.properties文件中文乱码
现象: 原因: 项目编码格式与IDEA编码格式不一致导致的 解决办法: 在File->Settings->Editor->File Encodings选项中,将Global Encoding,Project Encoding,Default encoding for properties files这三个选项置为一致&a…...
Rust 模块系统
文章目录 模块系统crate包cargo 创建库库的使用 模块系统 Rust的{模块系统|the module system},包括: * 包(Packages): Cargo 的一个功能,它允许你构建、测试和分享 crate。 * Crates :一个模…...
面向服务架构-架构师(六十四)
SOA概述和发展、参考架构、协议和规范、标准和原则、设计模式、构件和实施。 SOA概述和发展 服务指系统对外提供的功能,SOA是一种应用框架。 微服务去掉了ESB企业服务总线,SOA集中式,SOA和微服务的区别: 微服务更加精细。服务…...
Linux之系统编程
1.yum 1.yum list可以出现所有可下载的程序 辅助grep进行查找 2.yum install可以下载并安装 3.yum remove可以卸载程序 不同的商业操作系统内核都是一样的,主要是配套社区不一样。 开源组织,各大公司,既得利益者。 同上 基础软件源可以保证…...
信道数据传输速率、信号传播速度——参考《天勤计算机网络》
一、缘起题目 二、解析 三、总结 信道数据传输速率和信号传播速度是两个不同的概念。 3.1 信道数据传输速率(Channel Data Transfer Rate) 指的是在通信系统中,通过信道传输的数据量,通常以 比特率(bits per second…...
微信小程序vue+uniapp旅游景点门票预订系统 名胜风景推荐系统
与此同时越来越多的旅游公司建立了自己的基于微信小程序的名胜风景推荐平台,管理员通过网站可以添加用户、景点分类、景点信息、在线预订、最新推荐,用户可以对景点信息进行在线预订,以及开展电子商务等。互联网的世界里蕴藏无限生机…...
每日一题之二分查找(一)
每日一题之二分查找(一) 1.题目(搜索插入位置) 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间…...
Redisson的看门狗策略——保障Redis数据安全与稳定的机制
前言 自定义redis分布式锁无法自动续期,比如,一个锁设置了1分钟超时释放,如果拿到这个锁的线程在一分钟内没有执行完毕,那么这个锁就会被其他线程拿到,可能会导致严重的线上问题,在秒杀场景下,…...
2.2 消元法的概念
一、消元法介绍 消元法(elimination)是一个求解线性方程组的系统性方法。下面是使用消元法求解一个 2 2 2\times2 22 线性方程组的例子。消元之前,两个方程都有 x x x 和 y y y,消元后,第一个未知数 x x x 将从第…...
删除有序数组中的重复项
目录 题目: 示例: 题目分析: 解题思路: 题目: 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的…...
【数据库】
文章目录 1. 聚合函数练习: 2. 子查询 1. 聚合函数 where中过滤条件中不能写聚合函数,有聚合函数需要写到Having中 方式一效率高: Select执行流程 练习: 2. 第七题:count(*)有问题,原因是左外连接后…...
高级深入--day38
阳光热线问政平台 http://wz.sun0769.com/index.php/question/questionType?type4 爬取投诉帖子的编号、帖子的url、帖子的标题,和帖子里的内容。 items.py import scrapyclass DongguanItem(scrapy.Item):# 每个帖子的标题title scrapy.Field()# 每个帖子的编…...
基于springboot,vue校园社团管理系统
开发工具:IDEA 服务器:Tomcat9.0, jdk1.8 项目构建:maven 数据库:mysql5.7 系统分前后台,项目采用前后端分离 前端技术:vueelementUI 服务端技术:springbootmybatis-plus 本系…...
广州华锐互动:VR虚拟现实物理学习平台,开启数字化教学新格局
随着虚拟现实(VR)技术的不断发展,越来越多的领域开始应用这一技术。广州华锐互动开发的VR虚拟现实物理学习平台就得到了广泛应用,平台涉及力学、光学、热学等初中物理知识,还包含了物理名人、实验器具、物理现象的还原和学习,相比…...
【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…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
