Spring源码-从源码层面讲解传播特性
传播特性:service:REQUIRED,dao:REQUIRED
两个都是required使用的是同一个事务,正常情况,在service提交commit
<tx:advice id="myAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="checkout" propagation="REQUIRED" /><tx:method name="updateStock" propagation="REQUIRED" /></tx:attributes></tx:advice>
service:
public void checkout(String username,int id){try {bookDao.updateStock(id);} catch (Exception e) {e.printStackTrace();}}
dao:
public void updateStock(int id){String sql = "update book_stock set stock=stock-1 where id=?";jdbcTemplate.update(sql,id);for (int i = 1 ;i>=0 ;i--)System.out.println(10/i);}
dao层抛出异常导致

service层事务:外层开始没有事务所以这里是true

dao内层事务因为传播特性是required所以复用的是外层service事务


newSynchronization变为false

old是外层service,this是当前dao的

这里执行的sql不会实际生效因为没有commit,下面for会有异常 看看后续怎么处理异常再事务


completeTransactionAfterThrowing异常回滚


先处理回滚的规则,就是事务注解里的rollbackFor,rollbackForClassName,noRollbackFor,noRollbackForClassName属性如果没有设置就会调用父类的rollbackOn

super.rollbackOn(ex);

开始completeTransactionAfterThrowing的txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());


把外层事务信息恢复回去

开始打印异常信息

在service层捕获了异常没有抛 所以外层事务不回滚

在这里完成回滚

UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only异常在这里抛出

数据库数据不会被修改
service:REQUIRED,dao:NESTED
<tx:advice id="myAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="checkout" propagation="REQUIRED" /><tx:method name="updateStock" propagation="NESTED" /></tx:attributes></tx:advice>
PROPAGATION_NESTED为事务设置一个回退点


设置mysql连接的保存点

保存点设置完成

createAndHoldSavepoint:140, AbstractTransactionStatus (org.springframework.transaction.support)
handleExistingTransaction:490, AbstractPlatformTransactionManager (org.springframework.transaction.support)
getTransaction:356, AbstractPlatformTransactionManager (org.springframework.transaction.support)
createTransactionIfNecessary:588, TransactionAspectSupport (org.springframework.transaction.interceptor)
invokeWithinTransaction:367, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:125, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
invoke:100, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
intercept:721, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
updateStock:-1, BookDao$$EnhancerBySpringCGLIB$$421d7dae (com.mashibing.tx.xml.dao)
checkout:25, BookService (com.mashibing.tx.xml.service)
invoke:-1, BookService$$FastClassBySpringCGLIB$$66a1e40d (com.mashibing.tx.xml.service)
invoke:218, MethodProxy (org.springframework.cglib.proxy)
invokeJoinpoint:802, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceedWithInvocation:-1, 1079125839 (org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$47)
invokeWithinTransaction:374, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:125, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
invoke:100, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
intercept:721, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
checkout:-1, BookService$$EnhancerBySpringCGLIB$$d6fab840 (com.mashibing.tx.xml.service)
main:17, TxTest (com.mashibing.tx.xml)
代码执行到这里没有新建连接,用的是外层方法事务和连接。

在mysql中保存点的使用:
stock=100 设置保存点p1 后面会回滚到P1 就能实现一个事务中部分成功部分失败。stock最后变为97,说明前三个修改语句生效,后三个失败,保存点的作用就是保存保存点之前的sql生效。后边的会回滚不会实际生效

执行dao的内层方法抛异常,此时事务有保存点在这里执行回滚保存点的操作,并且把rollbackOnly变为false,来进行重置保存点。

外层service捕获异常,继续后续执行

直接执行下面的commit,上面的两个if进不去

此时执行的是service的外层事务,没有保存点直接执行docommit,外层方法正常提交结束。


service:REQUIRED,dao:REQUIRED_NEW
BookDao的内层方式这里能获取到threadlocal里的连接。

doGetTransaction:275, DataSourceTransactionManager (org.springframework.jdbc.datasource)
getTransaction:349, AbstractPlatformTransactionManager (org.springframework.transaction.support)
createTransactionIfNecessary:588, TransactionAspectSupport (org.springframework.transaction.interceptor)
invokeWithinTransaction:367, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:125, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
invoke:100, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
intercept:721, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
updateStock:-1, BookDao$$EnhancerBySpringCGLIB$$46f7c792 (com.mashibing.tx.xml.dao)
checkout:25, BookService (com.mashibing.tx.xml.service)
invoke:-1, BookService$$FastClassBySpringCGLIB$$66a1e40d (com.mashibing.tx.xml.service)
invoke:218, MethodProxy (org.springframework.cglib.proxy)
invokeJoinpoint:802, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceedWithInvocation:-1, 1988939205 (org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$47)
invokeWithinTransaction:374, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:125, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
invoke:100, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
intercept:721, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
checkout:-1, BookService$$EnhancerBySpringCGLIB$$dbd50224 (com.mashibing.tx.xml.service)
main:17, TxTest (com.mashibing.tx.xml)
存在外部事务

当前dao是PROPAGATION_REQUIRES_NEW,先挂起外层事务

SuspendedResourcesHolder 挂起
/*** 有些传播机制需要挂起当前的事务,比如NOT_SUPPORTED,REQUIRES_NEW首先会清除所有线程相关的同步状态,如果当前事务存在的话,就进行一些属性的清除,比如清空连接持有器,清空线程私有变量的同步状态,* 最后把当前事务清除的属性保存到一个SuspendedResourcesHolder里,以便于恢复的时候设置会去*/@Nullableprotected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {// 判断当前的线程变量中有没有激活的事物,有需要清空线程变量if (TransactionSynchronizationManager.isSynchronizationActive()) {List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();try {Object suspendedResources = null;if (transaction != null) {//挂起的资源,连接持有器suspendedResources = doSuspend(transaction);}// 获取当前事务名称String name = TransactionSynchronizationManager.getCurrentTransactionName();// 清空线程变量TransactionSynchronizationManager.setCurrentTransactionName(null);// 获取出只读事务的名称boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();// 清空线程变量TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);// 获取已存在事务的隔离级别Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();// 清空隔离级别TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);// 判断当前事务激活状态boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();// 清空标记TransactionSynchronizationManager.setActualTransactionActive(false);// 把上诉从线程变量中获取出来的存在事务属性封装为挂起的事务属性返回出去return new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);}catch (RuntimeException | Error ex) {// doSuspend failed - original transaction is still active...doResumeSynchronization(suspendedSynchronizations);throw ex;}}else if (transaction != null) {// Transaction active but no synchronization active.Object suspendedResources = doSuspend(transaction);return new SuspendedResourcesHolder(suspendedResources);}else {// Neither transaction nor synchronization active.return null;}}
doSuspend
清空连接持有器
/*** 实际挂起资源的方法* @param transaction the transaction object returned by {@code doGetTransaction}* @return*/@Overrideprotected Object doSuspend(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;// 清空连接持有器txObject.setConnectionHolder(null);// 解绑线程私有的资源return TransactionSynchronizationManager.unbindResource(obtainDataSource());}
实际处理挂起事务 清除threadlocal的副本

被挂起的历史事务相关属性信息

doBegin(transaction, definition);// 开启事务和连接
开启连接和事务
service层的事务和dao层的不关联,各自有各自的事务和数据库连接,内层回滚不影响外层的了
通过数据源获取一个数据库连接对象 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">// 通过数据源获取一个数据库连接对象 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">Connection newCon = obtainDataSource().getConnection();//从DruidDataSource获取连接if (logger.isDebugEnabled()) {logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");}// 把我们的数据库连接包装成一个ConnectionHolder对象 然后设置到我们的txObject对象中去txObject.setConnectionHolder(new ConnectionHolder(newCon), true);。。。。。。// 关闭自动提交 如果不i关闭每次sql执行就自动提交了if (con.getAutoCommit()) {//设置需要恢复自动提交txObject.setMustRestoreAutoCommit(true);if (logger.isDebugEnabled()) {logger.debug("Switching JDBC Connection [" + con + "] to manual commit");}// 关闭自动提交con.setAutoCommit(false);}。。。。。。// Bind the connection holder to the thread.// 绑定我们的数据源和连接到我们的同步管理器上,把数据源作为key,数据库连接作为value 设置到线程变量中if (txObject.isNewConnectionHolder()) {// 将当前获取到的连接绑定到当前线程 数据源和连接持久器进行绑定TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());}
后续执行dao层抛出异常
completeTransactionAfterThrowing:668, TransactionAspectSupport (org.springframework.transaction.interceptor)
invokeWithinTransaction:379, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:125, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
invoke:100, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
intercept:721, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
updateStock:-1, BookDao$$EnhancerBySpringCGLIB$$46f7c792 (com.mashibing.tx.xml.dao)
checkout:25, BookService (com.mashibing.tx.xml.service)
invoke:-1, BookService$$FastClassBySpringCGLIB$$66a1e40d (com.mashibing.tx.xml.service)
invoke:218, MethodProxy (org.springframework.cglib.proxy)
invokeJoinpoint:802, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceed:172, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
proceedWithInvocation:-1, 1988939205 (org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$47)
invokeWithinTransaction:374, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:125, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
invoke:100, ExposeInvocationInterceptor (org.springframework.aop.interceptor)
proceed:199, ReflectiveMethodInvocation (org.springframework.aop.framework)
proceed:780, CglibAopProxy$CglibMethodInvocation (org.springframework.aop.framework)
intercept:721, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
checkout:-1, BookService$$EnhancerBySpringCGLIB$$dbd50224 (com.mashibing.tx.xml.service)
main:17, TxTest (com.mashibing.tx.xml)



/*** 真正回滚的处理方法,也就是获取JDBC连接,然后回滚* @param status the status representation of the transaction*/@Overrideprotected void doRollback(DefaultTransactionStatus status) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();Connection con = txObject.getConnectionHolder().getConnection();if (status.isDebug()) {logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");}try {// jdbc的回滚con.rollback();}catch (SQLException ex) {throw new TransactionSystemException("Could not roll back JDBC transaction", ex);}}
cleanupAfterCompletion
/*** 回滚后的处理工作,如果是新的事务同步状态的话,要把线程的同步状态清除了,* 如果是新事务的话,进行数据清除,线程的私有资源解绑,重置连接自动提交,隔离级别,是否只读,释放连接等。* 如果有挂起的事务,还要把这个事务给恢复,其实就是把属性设置回去** Clean up after completion, clearing synchronization if necessary,* and invoking doCleanupAfterCompletion.* @param status object representing the transaction* @see #doCleanupAfterCompletion*/private void cleanupAfterCompletion(DefaultTransactionStatus status) {// 设置完成状态status.setCompleted();if (status.isNewSynchronization()) {// 线程同步状态清除TransactionSynchronizationManager.clear();}// 如果是新事务的话,进行数据清除,线程的私有资源解绑,重置连接自动提交,隔离级别,是否只读,释放连接等if (status.isNewTransaction()) {doCleanupAfterCompletion(status.getTransaction());}// 有挂起的事务要恢复if (status.getSuspendedResources() != null) {if (status.isDebug()) {logger.debug("Resuming suspended transaction after completion of inner transaction");}Object transaction = (status.hasTransaction() ? status.getTransaction() : null);// 结束之前事务的挂起状态resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());}}
resume恢复外层事务到本地线程,如果service方法有多个事务dao执行完一个dao需要将service的事务恢复到线程
/*** 如果前面有事务被挂起,现在就要回复,其实就是把一些属性设置回去** Resume the given transaction. Delegates to the {@code doResume}* template method first, then resuming transaction synchronization.* @param transaction the current transaction object* @param resourcesHolder the object that holds suspended resources,* as returned by {@code suspend} (or {@code null} to just* resume synchronizations, if any)* @see #doResume* @see #suspend*/protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)throws TransactionException {// 设置属性和状态if (resourcesHolder != null) {Object suspendedResources = resourcesHolder.suspendedResources;if (suspendedResources != null) {doResume(transaction, suspendedResources);}List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;//如果有挂起同步器的话要设置线程私有变量的值为挂起事务的相关属性if (suspendedSynchronizations != null) {TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);doResumeSynchronization(suspendedSynchronizations);}}}
service中对异常catch后续就不会处理异常 直接commit
public void checkout(String username,int id){try {bookDao.updateStock(id);} catch (Exception e) {e.printStackTrace();}}

1.如果service不catch异常会继续向外抛,最终会导致service层也会回滚 ,如此一来,service和dao一共回滚两次;即dao抛出没捕获,dao回滚,此时service捕获了就不回滚,没捕获也会回滚;
2.如果外层有异常抛出,内层正常执行,外层不会导致内层回滚,内层会影响外层,外层不会影响内层;即内外两层是不同事务,内层提交过了,外层有异常没捕获,外层事务回滚,此时内层事务不受影响
相关文章:
Spring源码-从源码层面讲解传播特性
传播特性:service:REQUIRED,dao:REQUIRED 两个都是required使用的是同一个事务,正常情况,在service提交commit <tx:advice id"myAdvice" transaction-manager"transactionManager"><tx:attributes&…...
Rust调用tree-sitter解析C语言
文章目录 一、Rust 调用 tree-sitter 解析 C 语言代码1. 设置 Rust 项目2. 添加 tree-sitter 依赖3. 编写 Rust 代码4. 运行程序5. 编译出错 二、解决步骤1. 添加 tree-sitter 构建依赖2. 添加 tree-sitter-c 源代码3. 修改 build.rs 以编译 tree-sitter-c 库4. 修改 Cargo.tom…...
奇瑞汽车—经纬恒润 供应链技术共创交流日 成功举办
2024年9月12日,奇瑞汽车—经纬恒润技术交流日在安徽省芜湖市奇瑞总部成功举办。此次盛会标志着经纬恒润与奇瑞汽车再次携手,深入探索汽车智能化新技术的前沿趋势,共同开启面向未来的价值服务与产品新篇章。 面对全球汽车智能化浪潮与产业变革…...
vue3 TagInput 实现
效果 要实现类似于下面这种效果 大致原理 其实是很简单的,我们可以利用 element-plus 组件库里的 el-tag 组件来实现 这里我们可以将其抽离成一个公共的组件,那么现在有一个问题就是通讯问题 这里我们可以利用父子组件之间的通讯,利用 v-model 来实现,父组件传值,子组…...
mysql中的json查询
首先来构造数据 查询department里面name等于研发部的数据 查询语句跟普通的sql语句差不多,也就是字段名要用到path表达式 select * from user u where u.department->$.name 研发部 模糊查询 select * from user u where u.department->$.name like %研发%…...
Etcd权限认证管理
1 查看是否开启权限认证 ctl auth status 2 开启权限认证 ctl auth enable。开启后每一条命令都要加上用户 --userroot:root(root默认最高权限) 3 创建其他用户 ctl user add user1 --user用户名:密码 4 创建角色 ctl role add testR --user 5 为角色添加权限 ctl role g…...
图文组合商标部分驳回后优化后初审通过!
这几天以前有个企业的商标初审下来了,以前是加了图形个别部分没有通过初审,后面是把图形去掉重新用文字申请下来初审。 图形与文字同时申请,会分别审查有一个元素过不了,整体就会过不了,所以平常就会建议分开申请注册商…...
【最新华为OD机试E卷-支持在线评测】爱吃蟠桃的孙悟空(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…...
BUUCTF [SCTF2019]电单车详解两种方法(python实现绝对原创)
使用audacity打开,发现是一段PT2242 信号 PT2242信号 有长有短,短的为0,长的为1化出来 这应该是截获电动车钥匙发射出的锁车信号 0 01110100101010100110 0010 0前四位为同步码0 。。。中间这20位为01110100101010100110为地址码0010为功…...
Apache James配置连接达梦数据库
项目场景: Apache James配置连接达梦数据库,其他配置中不存在的数据库也可参考此方案。 配置步骤 1、把需要的jar包导入到James 把DmJdbcDriver18.jar复制到下面lib目录下 james-2.3.2\lib 2、 修改连接配置 james-2.3.2\apps\james\SAR-INF\confi…...
Java实现栈
一、栈Stack 1.1 概念 一种特殊的线性表,只允许在固定的一段进行插入和删除元素操作。进行数据的插入和删除操作的一段称为栈顶,另一端称为栈低。栈中的元素遵循后进先出 LIFO(Last In First Out)的原则。 进栈 出栈 举例:在word中…...
数据结构—栈
栈 概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈…...
服务设计原则介绍
在Java或任何软件开发中,设计服务时遵循一些核心原则是非常重要的,这些原则不仅有助于构建高质量、可维护的软件系统,还能提高系统的可扩展性和可重用性。以下是一些关键的服务设计原则: 单一职责原则(SingleResponsib…...
【Qualcomm】高通SNPE框架的使用 | 原始模型转换为量化的DLC文件 | 在Android的DSP端运行模型
目录 ① 激活snpe环境 ② 设置环境变量 ③ 模型转换 ④ run 首先,默认SNPE工具已经下载并且Setup相关工作均已完成。同时,拥有原始模型文件,本文使用的模型文件为SNPE 框架示例的inception_v3_2016_08_28_frozen.pb文件。image_file_list…...
爬虫的流程
爬虫的流程 获取网页提取信息保存数据自动化程序能爬怎样的数据 获取网页 获取网页就是获取网页的源代码,源代码里包含了网页的部分有用信息,所以只要把源代码获取下来,就可以从中提取想要的信息浏览器访问网页的本质:浏览器向服…...
Git之如何删除Untracked文件(六十八)
简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【…...
k8s集群自动化管理
项目地址 https://github.com/TimeBye/kubeadm-ha准备安装包 # 离线安装环境 curl -LO https://oss.choerodon.com.cn/kubeadm-ha/kubeadm-ha-base-amd64.tar # 集群运行所需的镜像 curl -LO https://oss.choerodon.com.cn/kubeadm-ha/kubernetes-1.30.2-images-amd64.tgz # …...
yum库 docker的小白安装教程(附部分问题及其解决方案)
yum库 首先我们安装yum 首先在控制台执行下列语句 首先切换到root用户,假如已经是了就不用打下面的语句 su root #使用国内的镜像,不执行直接安装yum是国外的,那个有问题 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.al…...
python如何实现日期加减
首先通过import datetime,导入日期处理库。 然后把日期转化成datetime标准格式,使用datetime.datetime.strptime()方法将字符串格式的时间转化为标准格式。 其中"%Y/%m/%d %H:%M:%S"为time字符串的时间格式:Y为年,m为月…...
springboot实战学习笔记(4)(Spring Validation参数校验框架、全局异常处理器)
接着上篇博客学习。上篇博客是已经基本完成用户模块的注册接口的开发。springboot实战学习笔记(3)(Lombok插件、postman测试工具、MD5加密算法、post请求、接口文档、注解、如何在IDEA中设置层级显示包结构、显示接口中的方法)-CSDN博客本篇博客主要是关…...
永磁同步电机这玩意儿现在工业上用得是真多,今天咱们来点硬核的,手搓个IPMSM的数学模型。先别急着关页面,代码实现和调试坑点都给你备好了
IPMSM数学模型,模拟电机对不同输入的响应,包含速度环和电流环,输出电流转速和转矩。先甩几个核心方程镇楼。d-q轴电压方程: def voltage_equation(t, state, Vd, Vq):id, iq, w_r, theta stateVd ... # 这里放你的控制算法输出V…...
王二明古方草解毒茶商城模式解析
王二明古方草解毒茶商城模式解析:架构、争议与合规思考在社交电商与大健康产业的交叉赛道中,“王二明古方草解毒茶”凭借其独特的草本茶饮定位与多级分销模式,曾一度引发市场关注。该模式以产品为核心,通过数字化商城系统构建了一…...
Wan2.2-I2V-A14B镜像效果展示:夕阳海滩10秒1080P高清视频生成作品集
Wan2.2-I2V-A14B镜像效果展示:夕阳海滩10秒1080P高清视频生成作品集 1. 惊艳的视频生成效果 想象一下,只需简单描述,就能让电脑自动生成一段夕阳下的海滩视频。Wan2.2-I2V-A14B镜像让这个想象成为现实,它能将文字描述转化为高清…...
筑牢数据安全底座!百度智能云数据库GaiaDB分布式版通过『国密认证』
近日,百度智能云自研的关系型数据库GaiaDB分布式版获得由国家密码管理局商用密码检测认证中心颁发的《商用密码产品认证证书》,通过GM/T 0028《密码模块安全技术要求》安全等级第二级认证。这一认证标志着GaiaDB分布式版密码模块在密码安全设计、密钥管理…...
程序员必看!用UML类图破解Spring Boot领域模型设计难题
程序员必看!用UML类图破解Spring Boot领域模型设计难题 在Spring Boot项目中,领域模型设计往往是决定系统可维护性和扩展性的关键。许多Java开发者虽然熟练使用JPA和MyBatis,但当面对复杂的业务逻辑时,却常常陷入"贫血模型&q…...
小白友好:InstructPix2Pix极速推理,秒级响应你的修图指令
小白友好:InstructPix2Pix极速推理,秒级响应你的修图指令 你有没有过这样的经历?手机里存着一张照片,风景很美,但天空灰蒙蒙的;或者朋友聚会合影,大家都笑得很开心,就是背景有点乱。…...
MATLAB MultiDIC/Ncorr实战:从图像采集到应力应变云图生成的全流程解析
1. 数字图像相关技术入门指南 第一次接触数字图像相关(DIC)技术时,我完全被那些专业术语搞晕了。后来在实际项目中摸爬滚打才发现,这套技术本质上就是用相机"看"材料变形的过程。想象一下橡皮筋被拉伸时表面的斑点移动—…...
JPom结合Docker实现SpringBoot项目自动化构建与部署实战
1. 为什么你需要JPomDocker自动化部署方案 每次手动打包SpringBoot项目时,你是不是也经历过这样的痛苦?先在本地mvn clean package,然后scp上传到服务器,接着ssh连上去kill旧进程,最后nohup启动新jar包。更可怕的是半夜…...
RimSort:重新定义RimWorld模组管理的智能工具
RimSort:重新定义RimWorld模组管理的智能工具 【免费下载链接】RimSort 项目地址: https://gitcode.com/gh_mirrors/ri/RimSort 当你花费数小时手动调整上百个RimWorld模组的加载顺序,却依然遭遇游戏崩溃时;当你在多个平台间切换下载…...
HarmonyOS6 半年磨一剑 - RcCheckbox 实战下篇:问卷调查表单与参数使用指南
文章目录前言一、场景:问卷调查表单1.1 需求分析1.2 数据结构设计1.3 表单校验联动1.4 第三题:计数器与数量限制的配合1.5 结果页与状态重置1.6 三道题的样式差异化对比1.7 完整代码二、参数使用频率参考2.1 高频参数(必须掌握)2.…...
