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

Spring学习 Spring事务控制

7.1.事务介绍

7.1.1.什么是事务?

当你需要一次执行多条SQL语句时,可以使用事务。通俗一点说,如果这几条SQL语句全部执行成功,则才对数据库进行一次更新,如果有一条SQL语句执行失败,则这几条SQL语句全部不进行执行,这个时候需要用到事务。

刘德华《无间道》:去不了终点,回到原点

回顾一下数据库事务的四大特性ACID:

原子性(Atomicity)事务是最小的执行单位,不可再分割一致性(Consistency)事务前后的数据都是正确的隔离性(Isolation)事物之间相互隔离,互不干扰(并发执行的事务彼此无法看到对方的中间状态)持久性(Durability)事务一旦提交不可再回滚 

7.1.2.数据库本身控制事物

start transaction;#记录log(老数据)//1.本地数据库操作:张三减少金额//2.本地数据库操作:李四增加金额
rollback; #根据log恢复老数据
或
commit; #删除log

7.2.3.jdbc中使用事物

1.获取对数据库的连接

2.设置事务不自动提交(默认情况是自动提交的)

conn.setAutoCommit(false);   //其中conn是第一步获取的随数据库的连接对象。

3.把想要一次性提交的几个sql语句用事务进行提交

try{Statement stmt = null; stmt =conn.createStatement(); stmt.executeUpdate(sql1); int a=6/0;stmt.executeUpdate(Sql2); . . . conn.commit();   //使用commit提交事务 
}

4.捕获异常,进行数据的回滚(回滚一般写在catch块中)

catchException e) { ... conn.rollback(); 
}

7.2.转账案例

7.2.1.拷贝上一章代码

在这里插入图片描述

7.2.2.添加转账业务

7.2.2.1.mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.mapper.UserMapper">... ...<!--转账--><update id="updateUserOfSub">update t_user set money=money-#{money} where name=#{source}</update><update id="updateUserOfAdd">update t_user set money=money+#{money} where name=#{target}</update>
</mapper>
public interface UserMapper {... .../**扣钱*/void updateUserOfSub(@Param("source") String source, @Param("money") Float money);/*加钱*/void updateUserOfAdd(@Param("target") String target, @Param("money") Float money);
}
7.2.2.2.service
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;/*** 转账* @param source* @param target* @param money*/@Overridepublic void updateUser(String source, String target, Float money) {userMapper.updateUserOfSub(source, money);int a = 6/0;userMapper.updateUserOfAdd(target, money);}
}
7.2.2.3.测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//加载配置文件
public class ServiceTest {@Autowiredprivate UserService userService;/*** 转账业务*/@Testpublic void testUpdate(){userService.updateUser("张三丰","宋远桥",1F);}
}
  1. 此时我们观察数据表里面的变化情况:

    在这里插入图片描述

    转账是成功的,但是涉及到业务的问题,如果业务层实现类有其中一个环节出问题,都会导致灾难。

  2. 我们先把数据恢复到转账前。

    在这里插入图片描述

    现在我们故意模拟转账业务出现问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

再来测试:
在这里插入图片描述

业务执行出错,但是!

在这里插入图片描述

这是因为:不满足事务的一致性(减钱的事务提交了,加钱的事务没有提交,甚至都没有执行到)。

7.2.Spring中事务控制的API介绍

  • 说明:
    • JavaEE体系进行分层开发,事务处理位于业务层,Spring提供了分层设计业务层的事务处理解决方案。

    • Spring框架为我们提供了一组事务控制的接口。具体在后面的小节介绍。这组接口是在spring-tx.RELEASE.jar中。

    • spring的事务控制都是基于AOP的,它既可以使用编程的方式实现,也可以使用配置的方式实现。我们学习的重点是使用配置的方式实现。

7.2.1.PlatformTransactionManager

  • 此接口是spring的事务管理器,它里面提供了我们常用的操作事务的方法,源代码如下:

    public interface PlatformTransactionManager { //开启事务  TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; //提交事务void commit(TransactionStatus status) throws TransactionException; //回滚事务void rollback(TransactionStatus status) throws TransactionException;   
    } 
    
  • 真正管理事务的对象

    在这里插入图片描述

    Spring为不同的orm框架提供了不同的PlatformTransactionManager接口实现类:

    • DataSourceTransactionManager:使用Spring JDBC或iBatis 进行持久化数据时使用
    • HibernateTransactionManager:使用Hibernate版本进行持久化数据时使用

7.2.2.TransactionDefinition

  • TransactionDefinition接口包含与事务属性相关的方法,源代码如下:

    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;//传播行为int getPropagationBehavior();//隔离级别int getIsolationLevel();int getTimeout();boolean isReadOnly();
    }

    TransactionDefinition 接口定义的事务规则包括:事务隔离级别、事务传播行为、事务超时、事务的只读、回滚规则属性,同时,Spring 还为我们提供了一个默认的实现类:DefaultTransactionDefinition,该类适用于大多数情况。如果该类不能满足需求,可以通过实现 TransactionDefinition 接口来实现自己的事务定义。

7.2.2.1.事务隔离级别
  • 事务并发时的安全问题

    问题描述隔离级别
    脏读一个事务读取到另一个事务还未提交的数据read-commited
    不可重复读一个事务内多次读取一行数据的内容,其结果不一致repeatable-read
    幻读一个事务内多次读取一张表中的内容,其结果不一致serialized-read
  • Spring事务隔离级别(比数据库事务隔离级别多一个default)由低到高为:

    隔离级别
    ISOLATION_DEFAULT这是一个platfromtransactionmanager默认的隔离级别,使用数据库默认的事务隔离级别。
    ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,会产生脏读,不可重复读和幻像读。
    ISOLATION_READ_COMMITTED这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。 Oracle数据库默认的隔离级别。
    ISOLATION_REPEATABLE_READ这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻像读。MySQL数据库默认的隔离级别。
    ISOLATION_SERIALIZABLE这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读、不可重复读外,还避免了幻像读。
7.2.2.2.事务的传播行为
  • 什么是事务传播行为?

    事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
    例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

  • Spring定义了七种传播行为:

    事务传播行为类型说明
    PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择
    PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
    PROPAGATION_MANDATORY使用当前的事务,如果当前没有事务,就抛出异常。
    PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
    PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
    PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与REQUIRED类似的操作。
7.2.2.3.事务超时
  • timeout事务超时时间: 当前事务所需操作的数据被其他事务占用,则等待。
    • 100:自定义等待时间100(秒)。
    • -1:由数据库指定等待时间,默认值。(建议)
7.2.2.4.读写性
  • readonly 读写性
    • true:只读,可提高查询效率,适合查询

    • false:可读可写,适合增删改

7.2.2.5.回滚规则
  • TransactionAttribute

    TransactionAttribute 的默认实现类是DefaultTransactionAttribute ,它同时继承了DefaultTransactionDefinition。在DefaultTransactionDefinition 的基础上增加了rollbackOn的实现,DefaultTransactionAttribute的实现指定了,当异常类型为unchecked exception 的情况下将回滚事务。

在这里插入图片描述

  • rollbackOn 回滚规则,可省略或设置 rollbackOn=“Exception”

  • 如果事务中抛出 RuntimeException,则自动回滚

    • 如果事务中抛出 CheckException,不会自动回滚

7.3.3.TransactionStatus

  • PlatformTransactionManager.getTransaction(…) 方法返回一个 TransactionStatus 对象,该对象代表一个新的或已经存在的事务,源代码如下:

    public  interface TransactionStatus{boolean isNewTransaction();void setRollbackOnly();boolean isRollbackOnly();
    }
    

7.4.改造转账案例

7.4.1.applicationContext.xml

 	<!--配置事物管理器--><bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!--配置事物属性--><bean class="org.springframework.transaction.support.DefaultTransactionDefinition"><property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/><property name="readOnly" value="false"></property></bean>

7.4.2.service

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate TransactionDefinition txDefinition;@Autowiredprivate PlatformTransactionManager txManager;/*** 转账* @param source* @param target* @param money*/@Overridepublic void updateUser(String source, String target, Float money) {// 获取一个事务TransactionStatus txStatus = txManager.getTransaction(txDefinition);try {userMapper.updateUserOfSub(source, money);int a = 6/0;userMapper.updateUserOfAdd(target, money);//提交事务txManager.commit(txStatus);}catch (Exception e){//回滚事务txManager.rollback(txStatus);e.printStackTrace();}}
}

7.4.3.测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//加载配置文件
public class ServiceTest {@Autowiredprivate UserService userService;/*** 转账业务*/@Testpublic void testUpdate(){userService.updateUser("张三丰","宋远桥",1F);}
}
  • 事务回滚:

    在这里插入图片描述

  • 满足执行:

    在这里插入图片描述

  • 我们现在虽然实现了事务控制,但是代码非常的臃肿,我们可以使用动态代理简化代码

7.3.动态代理控制事务

7.3.1.factory

我们创建一个工厂,专门用来给 Service 创建代理对象,如下:

package com.by.factory;import com.by.service.UserService;
import com.by.service.UserServiceImpl;
import org.hamcrest.Factory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** bean工厂*/
@Component
public class BeanFactory {@Autowiredprivate UserService userService;@Autowiredprivate TransactionDefinition txDefinition;@Autowiredprivate PlatformTransactionManager txManager;/*** 获得UserServiceImpl对象** @return*/public UserService getUserService() {return (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),userService.getClass().getInterfaces(),new InvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {//开启事务TransactionStatus txStatus = txManager.getTransaction(txDefinition);try {method.invoke(userService, args);//提交事务txManager.commit(txStatus);} catch (Exception e) {//回滚事务txManager.rollback(txStatus);e.printStackTrace();}return null;}});}
}

7.3.2.applicationContext.xml

<!--配置service代理对象-->
<bean id="proxyService" factory-bean="beanFactory" factory-method="getUserService"></bean>

7.2.3.service

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;/*** 转账* @param source* @param target* @param money*/@Overridepublic void updateUser(String source, String target, Float money) {userMapper.updateUserOfSub(source, money);int a = 6/0;userMapper.updateUserOfAdd(target, money);}
}

7.2.4.测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ServiceTest {@Autowired@Qualifier("proxyService")//注入代理对象private UserService userService;@Testpublic void testUpdate(){userService.updateUser("张三丰","宋远桥",1F);}
}
  • 事务回滚:

在这里插入图片描述

7.4.Spring AOP控制事务

7.4.1.导入schema约束

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--配置事物属性<bean class="org.springframework.transaction.support.DefaultTransactionDefinition"><property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/><property name="readOnly" value="false"></property></bean>配置service代理对象<bean id="proxyService" factory-bean="beanFactory" factory-method="getUserService"> </bean>-->
</beans>    

7.4.2.配置增强

    <!-- 1、增强 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><!--事务属性--><tx:attributes><!-- 指定方法名称:是业务核心方法read-only:是否是只读事务。默认false,不只读。isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。propagation:指定事务的传播行为。timeout:指定超时时间。默认值为:-1。永不超时。rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。省略时任何异常都回滚。--><tx:method name="*" read-only="false" propagation="REQUIRED"/><tx:method name="select*" read-only="true" propagation="SUPPORTS"/><tx:method name="get*" read-only="true" propagation="SUPPORTS"/></tx:attributes></tx:advice>

7.4.3.配置切点

    <aop:config><!--2、切点--><aop:pointcut expression="execution(* com.by.service.*.*(..))" id="pointcut"/></aop:config>

7.4.4.配置切面

    <aop:config><!--3、切面--><aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor></aop:config>

7.4.5.factory

删除bean工程

7.4.6.测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//加载配置文件
public class ServiceTest {@Autowiredprivate UserService userService;/*** 转账业务*/@Testpublic void testUpdate(){userService.updateUser("张三丰","宋远桥",1F);}
}
  • 事务回滚:

    在这里插入图片描述

  • 问题一:如果我们把方法名称改了,那么事务还会回滚吗?

    • 修改applicationContext.xml:

    在这里插入图片描述

    • 修改service:

  • 问题二:如果我们把异常捕捉了,那么事务还会回滚吗?

相关文章:

Spring学习 Spring事务控制

7.1.事务介绍 7.1.1.什么是事务&#xff1f; 当你需要一次执行多条SQL语句时&#xff0c;可以使用事务。通俗一点说&#xff0c;如果这几条SQL语句全部执行成功&#xff0c;则才对数据库进行一次更新&#xff0c;如果有一条SQL语句执行失败&#xff0c;则这几条SQL语句全部不…...

c++一些使用频率较高的库函数

目录 memset&#xff08;&#xff09; memset&#xff08;&#xff09;接受三个参数&#xff1a; 注意 swap&#xff08;&#xff09; reverse&#xff08;&#xff09; reverse函数接收两个参数&#xff1a; reverse&#xff08;&#xff09;反转整形向量元素顺序示例 …...

【从零开始学技术】Fiddler 抓取 https 请求大全

1.Fiddler代理浏览器设置 注意浏览器代理区别 Chrome/IE浏览器使用的都是系统代理设置 在chrome浏览器的设置中搜索代理&#xff0c;可以看到 打开IE浏览器&#xff0c;选择设置->Internet选项 Firefox浏览器使用的是单独的一套代理系统 在Firefox的代理设置中&#xff0c;我…...

第二百六十四回

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了SliverPadding组件相关的内容&#xff0c;本章回中将介绍Sliver综合示例.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在前面的章回中介绍了各种Sliver相关的组件&#xff1a;SliverList,SliverGr…...

用Kimi chat识别并整理图片里面的文字

Kimi chat是有OCR功能的&#xff0c;可以识别图片中的文字。 下面这张图片是一本书的注释&#xff0c;里面提到有不少图书&#xff0c;利用Kimi chat就可以轻松完成提取其中图书书名的任务。 先拿一张图片来做实验。Kimichat的回复&#xff1a; 在您提供的文件内容中&#xf…...

驾驭未来:从传统运维到智能化运维的转型之路

随着科技的飞速发展&#xff0c;企业的业务需求也在不断变化。为了满足这些需求&#xff0c;企业的IT架构逐渐向云原生、容器化和微服务化演进。作为支撑企业业务发展的运维人员&#xff0c;我们需要紧跟时代步伐&#xff0c;不断提升自己的技能和认知水平。 在2023年全球运维大…...

LabVIEW在旋转机械故障诊断中的随机共振增强应用

在现代工业自动化领域&#xff0c;准确的故障诊断对于保障机械设备的稳定运行至关重要。传统的故障检测方法往往因噪声干扰而难以捕捉到微弱的故障信号。随着LabVIEW在数据处理和系统集成方面的优势日益凸显&#xff0c;其在旋转机械故障诊断中的应用开始发挥重要作用&#xff…...

尚硅谷大数据技术-数据湖Hudi视频教程-笔记02【核心概念(基本概念、数据写、数据读)】

大数据新风口&#xff1a;Hudi数据湖&#xff08;尚硅谷&Apache Hudi联合出品&#xff09; B站直达&#xff1a;https://www.bilibili.com/video/BV1ue4y1i7na 尚硅谷数据湖Hudi视频教程百度网盘&#xff1a;https://pan.baidu.com/s/1NkPku5Pp-l0gfgoo63hR-Q?pwdyyds阿里…...

鸿蒙(HarmonyOS)应用开发指南

1. 概述 1.1 简介 鸿蒙&#xff08;即 HarmonyOS &#xff0c;开发代号 Ark&#xff0c;正式名称为华为终端鸿蒙智能设备操作系统软件&#xff09;是华为公司自 2012 年以来开发的一款可支持鸿蒙原生应用和兼容 AOSP 应用的分布式操作系统。该系统利用“分布式”技术将手机、电…...

Android 13 辅助屏导航栏不显示问题

问题 在Android 13 上开启辅助屏幕。但是发现辅助屏systemui 导航按 icon没有显示&#xff0c;但是点击对应的区域有作用 分析 可以用 anroid device monitor 工具分析视图 解决 public NavigationBarView(Context context, AttributeSet attrs) {super(context, attrs);…...

【QT】标准对话框

目录 1 概述 2 QFileDialog对话框 1.选择打开一个文件 2.选择打开多个文件 3&#xff0e;选择已有目录 4&#xff0e;选择保存文件名 3 QColorDialog对话框 4 QFontDialog对话框 5 QInputDialog标准输入对话框 1.输入文字 2&#xff0e;输入整数 3&#xff0e;输入…...

微信小程序跳转方式及问题

一、五种跳转方式 1.wx.navigateTo() 保留当前页面&#xff0c;跳转到应用内的某个页面。但是不能跳到 tabbar 页面 通常推荐使用 wx.navigateTo进行跳转&#xff0c;以便返回原页面&#xff0c;以提高加载速度 wx.navigateTo({url: })2.wx.redirectTo() 关闭当前页面&#x…...

Redis实现分布式会话

Redis实现分布式会话 1 什么是分布式会话 1 这是我么之前学过的注册登录模式 2 如果非常多的人访问&#xff0c;因为单台服务器的访问承受能力是有限的&#xff0c;那么我们就想用多态服务器来承担压力 3 一般通过负载均衡的方式来实现&#xff0c;来分担服务器的压力。 4 负…...

AntDesignBlazor示例——暗黑模式

本示例是AntDesign Blazor的入门示例&#xff0c;在学习的同时分享出来&#xff0c;以供新手参考。 示例代码仓库&#xff1a;https://gitee.com/known/BlazorDemo 1. 学习目标 暗黑模式切换查找组件样式覆写组件样式 2. 添加暗黑模式切换组件 1&#xff09;双击打开MainL…...

高通平台开发系列讲解(USB篇)adb function代码分析

文章目录 一、FFS相关动态打印二、代码入口三、ffs_alloc_inst四、ep0、ep1&ep2的注册五、读写过程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本文主要介绍高通平台USB adb function代码f_fs.c。 一、FFS相关动态打印 目录:msm-4.14/drivers/usb/gadget/fun…...

SQL基础知识3

一、删除数据 1、delete操作 删除之前一定要查询一下&#xff0c;确保删除的数据是对的 逻辑删除&#xff1a;在表中新增一个字段&#xff1a;flag/status 二、更新数据 本质上的逻辑删除 三、查询数据 1、联表查询 1、内连接 交集的部分叫内连接 小知识&#xff1a;一般…...

GBASE南大通用数据库如何检索单行

SELECT 语句返回的行集是它的活动集。单个 SELECT 语句返回单个行。您可使用嵌入式 SELECT 语句来从数据库将单个行检索到主变量内。然而&#xff0c;当 SELECT 语句返回多行数 据时&#xff0c;程序必须使用游标来一次检索一行。在 检索多行 中讨论“多行”选择操作。 要检索单…...

【数据结构与算法】单链表(无头单向非循环)

文章目录 1. 概念2. 链表分类3. 链表与顺序表对比4. 无头单向非循环链表实现&#xff08;C语言&#xff09;4.1 SingleLinkedList.h4.2 Test.c4.3 SingleLinkedList.c 1. 概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指…...

C#PDF转Excel

組件 Spire.Pdf.dll, v7.8.9.0 【注意&#xff1a;版本太低的没有此功能】 在Visual Studio中找到参考&#xff0c;鼠标右键点击“引用”&#xff0c;“添加引用”&#xff0c;将本地路径debug文件夹下的dll文件添加引用至程序。 界面图&#xff1a; 1个label&#xff0c;1…...

vivado xsim 终端 模拟

只模拟的话直接终端运行会快很多 计数器举例 mkdir srccounter.v module counter(input wire clk,input wire rst_n,output reg[31:0] cnt ); always (posedge clk or negedge rst_n)if(!rst_n)cnt < 31h0;elsecnt < cnt1;endmodule tb.v module tb; wire[31:0] out…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

【java面试】微服务篇

【java面试】微服务篇 一、总体框架二、Springcloud&#xff08;一&#xff09;Springcloud五大组件&#xff08;二&#xff09;服务注册和发现1、Eureka2、Nacos &#xff08;三&#xff09;负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...

C++中vector类型的介绍和使用

文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...