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

Spring和Spring Boot事务讲解和案例示范

引言

Spring框架提供了强大的事务管理支持,使得开发者能够更轻松地实现事务控制。在本篇文章中,我们将深入探讨Spring的事务管理机制,特别是编程式事务管理、声明式事务管理以及在多数据源环境下的事务处理。

第一章 编程式事务管理

编程式事务管理是指开发者在代码中手动控制事务的生命周期。对于基于POJO(Plain Old Java Object)的应用,这种方式是唯一的选择。编程式事务管理通常使用Spring的TransactionManager接口来实现事务的开始、提交和回滚。以下是编程式事务管理的一些重要概念和步骤。

1. 编程式事务管理的基本步骤

在编程式事务管理中,开发者需要显式地调用beginTransaction()commit()rollback()等方法来管理事务。以下是实现这一过程的步骤:

  1. 获取PlatformTransactionManager实例:通过Spring的应用上下文获取事务管理器实例。
  2. 创建事务定义:定义事务的传播行为和隔离级别等属性。
  3. 开始事务:通过事务管理器的getTransaction()方法获取当前事务。
  4. 执行业务逻辑:在事务中执行需要原子性的数据操作。
  5. 提交或回滚事务:根据业务逻辑的执行结果选择提交或回滚。
2. 示例代码

下面是一个简单的电子商务交易系统中编程式事务管理的示例代码。假设我们有一个OrderService类,用于处理订单的创建:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;public class OrderService {@Autowiredprivate PlatformTransactionManager transactionManager;public void createOrder(Order order) {// 定义事务属性DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);// 开始事务TransactionStatus status = transactionManager.getTransaction(def);try {// 执行业务逻辑,例如保存订单saveOrder(order);// 提交事务transactionManager.commit(status);} catch (Exception e) {// 回滚事务transactionManager.rollback(status);throw new RuntimeException("Failed to create order", e);}}private void saveOrder(Order order) {// 保存订单到数据库的逻辑}
}

在上面的代码中,我们首先定义了事务的传播行为为PROPAGATION_REQUIRED,这意味着如果当前存在事务,则加入该事务;否则新建一个事务。接着,通过transactionManager.getTransaction(def)开始事务,执行业务逻辑后根据情况决定提交或回滚事务。

3. 编程式事务管理的优缺点

优点:

  • 灵活性高:开发者可以在代码中完全控制事务的执行过程,适合复杂业务逻辑的处理。
  • 透明性:可以清晰地看到每一步的事务处理过程,便于调试。

缺点:

  • 代码冗长:每次处理事务都需要写大量的代码,降低了可读性和可维护性。
  • 容易出错:手动管理事务增加了出错的可能性,尤其是在复杂的业务流程中。

第二章 声明式事务管理

声明式事务管理是Spring框架提供的一种简化事务处理的方式,允许开发者通过配置而非代码控制事务的行为。这种方式大大降低了代码的复杂性,提升了可维护性和可读性。声明式事务管理可以通过XML配置或者注解(如@Transactional)来实现。

1. 使用TransactionProxyFactoryBean

TransactionProxyFactoryBean是Spring提供的一种基于代理的声明式事务管理方式。通过配置此Bean,开发者可以定义事务的边界,而不需要在业务逻辑中显式地处理事务。

示例代码

首先,在Spring的配置文件中定义一个TransactionProxyFactoryBean

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
</bean><bean id="orderService" class="com.example.OrderService"><property name="dataSource" ref="dataSource"/>
</bean><bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="target" ref="orderService"/><property name="transactionManager" ref="transactionManager"/><property name="transactionAttributes"><map><entry key="createOrder" value="PROPAGATION_REQUIRED"/></map></property>
</bean>

在上面的示例中,TransactionProxyFactoryBeanOrderService作为目标Bean,定义createOrder方法的事务属性为PROPAGATION_REQUIRED

2. 基于@Transactional的声明式事务管理

随着Spring 2.0引入的@Transactional注解,声明式事务管理变得更加简单和直观。通过在方法或类上添加该注解,开发者可以指定该方法或类所需的事务属性。

示例代码

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class OrderService {@Transactional(propagation = Propagation.REQUIRED)public void createOrder(Order order) {// 保存订单逻辑saveOrder(order);}private void saveOrder(Order order) {// 数据库保存逻辑}
}

在上面的代码中,@Transactional注解自动为createOrder方法添加了事务管理,开发者不再需要手动管理事务的开始和提交。

3. 事务传播行为

Spring定义了多种事务传播行为,开发者可以根据业务需求选择合适的策略。常用的传播行为包括:

  • PROPAGATION_REQUIRED:如果当前有事务,则加入该事务;否则新建一个事务。
  • PROPAGATION_REQUIRES_NEW:总是新建一个事务。
  • PROPAGATION_NESTED:如果当前有事务,则嵌套事务;否则新建一个事务。

第三章 基于AspectJ的AOP配置事务

AspectJ是Spring提供的强大AOP支持,能够在方法执行前后进行横切逻辑处理。在基于AspectJ的配置中,事务管理是通过切面(Aspect)来实现的,这样可以将事务逻辑与业务逻辑分离,使得代码更加清晰。

1. AspectJ事务管理的配置

为了使用AspectJ配置事务管理,首先需要在Spring配置中启用AspectJ支持:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.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.xsd"><tx:annotation-driven transaction-manager="transactionManager"/><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean></beans>
2. 创建切面

接下来,创建一个切面类来处理事务逻辑:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.transaction.annotation.Transactional;@Aspect
public class TransactionAspect {@Pointcut("execution(* com.example..*(..))") // 定义切入点public void transactionPointcut() {}@Transactionalpublic void aroundTransaction(ProceedingJoinPoint joinPoint) throws Throwable {try {joinPoint.proceed(); // 执行目标方法} catch (Throwable ex) {// 处理异常逻辑throw ex;}}
}

在上面的代码中,TransactionAspect类定义了一个切入点,用于匹配com.example包下的所有方法,并在方法执行前后处理事务。

3. 优缺点分析

优点:

  • 解耦性:业务逻辑与事务逻辑分离,提高了代码的可读性。
  • 可复用性:切面可以在多个业务逻辑中复用,减少代码重复。

缺点:

  • 学习曲线:对于初学者来说,AOP的概念和配置可能会增加学习难度。
  • 性能开销:切面处理增加了一定的性能开销,尤其是在高频调用的场景下。

第四章 多数据源下的事务管理

在复杂的电子商务系统中,往往需要使用多个数据源来存储不同类型的数据。例如,一个系统可能需要一个数据源来存储用户信息,另一个数据源来存储订单数据。处理多数据源的事务管理是一个重要的挑战,因为不同的数据源之间的事务管理需要确保一致性和隔离性。

1. 多数据源的配置

在Spring中,可以通过配置多个DataSource来支持多数据源。以下是一个简单的多数据源配置示例:

<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/db1"/><property name="username" value="user1"/><property name="password" value="password1"/>
</bean><bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/db2"/><property name="username" value="user2"/><property name="password" value="password2"/>
</bean>
2. 配置事务管理器

对于多数据源,我们需要配置一个ChainedTransactionManager,以便在同一个事务中管理多个数据源:

<bean id="transactionManager" class="org.springframework.transaction.support.TransactionSynchronizationManager"><property name="transactionManagers"><list><ref bean="dataSource1TransactionManager"/><ref bean="dataSource2TransactionManager"/></list></property>
</bean><bean id="dataSource1TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource1"/>
</bean><bean id="dataSource2TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource2"/>
</bean>
3. 使用@Transactional管理多数据源事务

在多数据源的场景中,使用@Transactional注解时需要明确指定事务管理器,以确保事务能够跨多个数据源进行管理:

import org.springframework.transaction.annotation.Transactional;public class OrderService {@Transactional(transactionManager = "transactionManager")public void createOrder(Order order, User user) {// 保存订单到dataSource1saveOrder(order);// 保存用户到dataSource2saveUser(user);}
}

在上述代码中,@Transactional注解的transactionManager属性指定了事务管理器,这样可以确保在createOrder方法中对多个数据源的操作都在同一个事务内执行。

4. 事务的一致性与隔离性

在多数据源环境下,确保事务的一致性和隔离性是非常重要的。开发者需要关注以下几个方面:

  • 事务传播行为:确保操作在同一事务中执行,避免出现部分提交的情况。
  • 隔离级别:根据业务需求选择合适的隔离级别,防止数据竞争和不可重复读等问题。

第五章 rollbackFor 属性

1. 默认事务回滚行为

默认情况下,Spring对事务的回滚行为如下:

  • 自动回滚:当抛出 RuntimeException 或其子类异常时,事务会自动回滚。
  • 不回滚:当抛出 Exception(即检查型异常)时,事务不会自动回滚,除非显式指定。

例如,以下代码在抛出 RuntimeException 时会回滚事务,但抛出 Exception 时不会回滚:

@Transactional
public void processOrder(Order order) throws Exception {// 订单处理逻辑if (someConditionFails()) {throw new Exception("订单处理失败!"); // 默认不会回滚事务}if (someOtherConditionFails()) {throw new RuntimeException("订单处理过程中出现运行时错误!"); // 默认会回滚事务}
}

在上述示例中,Exception 是检查型异常,Spring不会自动回滚它引发的事务。

2. 使用 rollbackFor 属性进行异常回滚控制

如果我们希望在抛出 Exception 或其他检查型异常时也回滚事务,可以通过 @Transactional 注解的 rollbackFor 属性来指定需要回滚的异常类型。

示例:指定在抛出 Exception 时回滚事务

@Transactional(rollbackFor = Exception.class)
public void processOrder(Order order) throws Exception {// 订单处理逻辑if (someConditionFails()) {throw new Exception("订单处理失败!"); // 现在会回滚事务}if (someOtherConditionFails()) {throw new RuntimeException("订单处理过程中出现运行时错误!"); // 依然会回滚事务}
}

在这个示例中,@Transactional(rollbackFor = Exception.class) 明确指定了当 Exception 被抛出时,事务也会回滚。

使用多个异常类型

可以指定多个异常类型,在多个异常类型下触发事务回滚:

@Transactional(rollbackFor = {Exception.class, SQLException.class})
public void processOrder(Order order) throws Exception {// 订单处理逻辑if (someConditionFails()) {throw new SQLException("数据库异常!"); // 现在会回滚事务}if (someOtherConditionFails()) {throw new Exception("订单处理失败!"); // 现在会回滚事务}
}
3. 在电商交易系统中的应用示例

在电商交易系统中,处理订单的过程中可能会发生多种不同类型的异常。比如,订单处理中可能抛出数据库相关的 SQLException,或者业务逻辑失败的 BusinessException。我们可以通过 rollbackFor 指定这些异常类型,以确保订单处理过程中发生这些异常时事务会正确回滚。

示例:电商系统中的订单处理

public class OrderService {@Transactional(rollbackFor = {SQLException.class, BusinessException.class})public void processOrder(Order order) throws BusinessException, SQLException {// 更新库存updateInventory(order);// 扣款操作if (!deductPayment(order)) {throw new BusinessException("扣款失败!");}// 提交订单if (!submitOrder(order)) {throw new SQLException("订单提交失败!");}}private void updateInventory(Order order) {// 库存更新逻辑}private boolean deductPayment(Order order) {// 扣款逻辑return false; // 模拟扣款失败}private boolean submitOrder(Order order) throws SQLException {// 订单提交逻辑return false; // 模拟数据库异常}
}

在上述示例中:

  • 如果 deductPayment 方法失败,会抛出 BusinessException,这将导致事务回滚。
  • 如果 submitOrder 方法失败,抛出的 SQLException 也会触发事务回滚。

第六章 Spring Boot 中使用 @Transactional 注解

在Spring Boot项目中,使用@Transactional注解非常简单,它主要用于控制业务逻辑中的事务处理,确保数据库操作的原子性。Spring Boot自动集成了事务管理,因此你无需进行过多的配置,只需要在方法或类上使用@Transactional注解即可。

1. Spring Boot 中的基本事务配置

默认情况下,Spring Boot会自动为你的项目启用事务管理。你只需要添加以下依赖:

Maven依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Spring Boot使用spring-boot-starter-data-jpa为JPA提供支持,事务管理器会自动配置。

2. 启用事务管理

在Spring Boot中,事务管理默认是启用的。如果你使用的是非Spring Boot项目,你可能需要使用@EnableTransactionManagement注解来启用事务管理。但在Spring Boot中,默认就支持该功能,无需额外配置。

如果需要显式启用,可以通过在配置类上添加@EnableTransactionManagement注解:

@Configuration
@EnableTransactionManagement
public class TransactionConfig {// 自定义事务管理器(如果需要)
}
3. 使用 @Transactional 注解

@Transactional 注解可以用在类或方法上,控制在这些方法中的所有数据库操作是否作为一个事务执行。默认情况下,它会对运行时异常进行回滚。

在方法上使用 @Transactional
@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Transactionalpublic void processOrder(Order order) {// 执行数据库操作,例如保存订单orderRepository.save(order);// 执行其他相关操作,例如更新库存updateInventory(order);// 如果任何操作失败,抛出异常,事务将回滚if (!order.isValid()) {throw new RuntimeException("订单验证失败,事务回滚!");}}private void updateInventory(Order order) {// 更新库存逻辑}
}

在上面的示例中,processOrder方法标记为@Transactional,如果方法中抛出了RuntimeException或其子类的异常,所有的数据库操作都会被回滚。

在类上使用 @Transactional

你也可以将@Transactional注解应用于类上,标记类中的所有公共方法都参与事务管理:

@Service
@Transactional
public class OrderService {@Autowiredprivate OrderRepository orderRepository;public void processOrder(Order order) {orderRepository.save(order);}public void cancelOrder(Long orderId) {orderRepository.deleteById(orderId);}
}

在这个类中,processOrdercancelOrder方法都将在事务中运行,任何一个方法抛出异常都会导致事务回滚。

4. 事务的传播行为和隔离级别

你可以通过@Transactional注解的属性自定义事务的传播行为和隔离级别:

  • 传播行为:可以通过propagation属性控制,默认值为Propagation.REQUIRED。例如,如果一个事务已经存在,Spring将加入到该事务中;如果不存在,则创建一个新的事务。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createNewOrder(Order order) {orderRepository.save(order);
}
  • 隔离级别:可以通过isolation属性设置,控制数据库并发访问的行为。默认值为Isolation.DEFAULT,即使用数据库的默认隔离级别。
@Transactional(isolation = Isolation.SERIALIZABLE)
public void updateOrder(Order order) {orderRepository.save(order);
}
5. 完整的 Spring Boot 事务管理案例

接下来,我们将构建一个完整的Spring Boot事务管理示例,展示如何使用@Transactional注解处理事务。

项目结构
src├── main│   ├── java│   │   └── com.example.transactiondemo│   │       ├── TransactionDemoApplication.java│   │       ├── model│   │       │   └── Order.java│   │       ├── repository│   │       │   └── OrderRepository.java│   │       └── service│   │           └── OrderService.java├── resources│   └── application.properties
5.1 Order 实体类
package com.example.transactiondemo.model;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;@Entity
public class Order {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String description;private boolean valid;// Getters and Setters
}
5.2 OrderRepository 接口
package com.example.transactiondemo.repository;import com.example.transactiondemo.model.Order;
import org.springframework.data.jpa.repository.JpaRepository;public interface OrderRepository extends JpaRepository<Order, Long> {
}
5.3 OrderService 服务类
package com.example.transactiondemo.service;import com.example.transactiondemo.model.Order;
import com.example.transactiondemo.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Transactionalpublic void processOrder(Order order) {// 保存订单orderRepository.save(order);// 假设更新库存出错,抛出异常if (!order.isValid()) {throw new RuntimeException("订单无效,事务回滚!");}}@Transactionalpublic void cancelOrder(Long orderId) {orderRepository.deleteById(orderId);}
}
5.4 TransactionDemoApplication 应用启动类
package com.example.transactiondemo;import com.example.transactiondemo.model.Order;
import com.example.transactiondemo.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class TransactionDemoApplication implements CommandLineRunner {@Autowiredprivate OrderService orderService;public static void main(String[] args) {SpringApplication.run(TransactionDemoApplication.class, args);}@Overridepublic void run(String... args) throws Exception {// 创建并处理订单Order order = new Order();order.setDescription("新订单");order.setValid(false);  // 模拟订单无效,抛出异常回滚事务try {orderService.processOrder(order);} catch (RuntimeException e) {System.out.println("事务回滚,订单处理失败!");}}
}
5.5 配置文件 application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/transactiondemo
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
5.6 运行结果

当运行该应用程序时,创建的订单由于 valid 属性设置为 false,会触发异常,导致事务回滚。数据库中不会插入该订单的数据,保证了数据的完整性和一致性。

第七章 常见问题及解决方案

在实际开发中,使用Spring事务管理时可能会遇到一些常见问题。以下是一些常见问题及其解决方案:

1. 事务未生效

问题:在使用@Transactional时,事务未生效,方法执行后数据仍然被提交。

解决方案

  • 确保方法是public的,Spring的代理机制要求事务方法必须是公共的。
  • 确保使用@Transactional注解的方法被Spring管理,即该方法不能在同一类中被直接调用。
2. 数据库连接泄漏

问题:由于长时间未关闭数据库连接,导致连接池资源耗尽。

解决方案

  • 确保在每个事务结束后正确关闭连接,Spring会自动处理事务结束时的连接释放。
  • 在使用编程式事务时,确保在异常处理逻辑中回滚事务并关闭连接。
3. 事务回滚未生效

问题:当异常发生时,事务未按预期回滚。

解决方案

  • 默认情况下,Spring只会对运行时异常(RuntimeException)进行回滚,确保抛出的异常类型是运行时异常。
  • 可以在@Transactional注解中设置rollbackFor属性,指定需要回滚的异常类型。
4. 多数据源事务管理问题

问题:在多数据源环境下,事务提交不一致,部分数据提交成功,部分数据失败。

解决方案

  • 确保使用ChainedTransactionManager或类似的事务管理器来处理多个数据源的事务。
  • 检查每个数据源的事务配置,确保一致性和正确的事务传播行为。

相关文章:

Spring和Spring Boot事务讲解和案例示范

引言 Spring框架提供了强大的事务管理支持&#xff0c;使得开发者能够更轻松地实现事务控制。在本篇文章中&#xff0c;我们将深入探讨Spring的事务管理机制&#xff0c;特别是编程式事务管理、声明式事务管理以及在多数据源环境下的事务处理。 第一章 编程式事务管理 编程式…...

前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比

这篇属于番外&#xff0c;属于技术性的讨论文&#xff0c;主要谈一下可能困惑不少人的问题。meteor看似一个前后端混合的框架&#xff0c;但实际上它并不是前后端混合的&#xff0c;只是共享了一个数据结构&#xff08;数据对象&#xff09;。现实中很多团队都说是前后端分离的…...

OJ在线评测系统 微服务 OpenFeign调整后端下 nacos注册中心配置 不给前端调用的代码 全局引入负载均衡器

OpenFeign内部调用二 4.修改各业务服务的调用代码为feignClient 开启nacos注册 把Client变成bean 该服务仅内部调用&#xff0c;不是给前端的 将某个服务标记为“内部调用”的目的主要有以下几个方面&#xff1a; 安全性: 内部API通常不对外部用户公开&#xff0c;这样可以防止…...

QD1-P19 HTML 总结

本节简单总结&#xff1a;《前端学习笔记1》专题前18篇文章关于HTML的内容。 下一节开始学习CSS了。HTML还是挺易学的&#xff0c;比Linux命令容易。 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p19 ‍ 在前面18节中&#xff0c;我们了解了HTML的基础知识&#xff1a; …...

Android Framework AMS(03)AMS关键类解读

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要涉AMS的关键类及其设计理念的解读&#xff0c;主要关注图中下方AMS关键类解读部分即可。这么做的目的是为了后面章节分析AMS时更容易理解…...

Pygame开发贪吃蛇

Pygame专为Python设计&#xff0c;支持多平台&#xff08;如Windows、Mac OS X、Linux、Android等&#xff09;&#xff0c;提供简单易用的API来创建2D游戏。它不仅仅局限于游戏开发&#xff0c;还可用于图形界面和音频应用。 Pygame提供了简洁的API&#xff0c;使得开发者可以…...

Linux进程间通信(个人笔记)

Linux进程通信 1.进程通信介绍1.1进程间通信目的1.2进程间通信发展1.3进程间通信的具体分类 2.管道2.1匿名管道2.1.1代码实例2.1.2 fork共享管道原理2.1.3 管道的读写规则与特点2.1.4 进程池 2.2 命名管道2.2.1 命名管道的创建2.2.2匿名管道与命名管道的区别2.2.3代码实例 3.Sy…...

SAP S/4HANA 迁移:IT 高管实用指南

新版《通往SAP S/4HANA之路》指南为计划从SAP ERP或SAP S/4HANA本地版本迁移到云端的组织提供了全面的参考。随着数字化转型的加速&#xff0c;尤其是在面临挑战的汽车行业等领域&#xff0c;企业必须采用云ERP解决方案&#xff0c;例如SAP S/4HANA云私有版&#xff0c;以应对瞬…...

Qt源码-Qt多媒体音频框架

Qt 多媒体音频框架 一、概述二、音频设计1. ALSA 基础2. Qt 音频类1. 接口实现2. alsa 插件实现 一、概述 环境详细Qt版本Qt 5.15操作系统Deepin v23代码工具Visual Code源码https://github.com/qt/qtmultimedia/tree/5.15 这里记录一下在Linux下Qt 的 Qt Multimedia 模块的设…...

卸载PLSQL及标准卸载流程

目录 1. 卸载PLSQL2. 删除注册表3. 删除数据信息 1. 卸载PLSQL 等待进度条走完 2. 删除注册表 regedit 右击删除 3. 删除数据信息 由于AppData是隐藏文件&#xff0c;需要勾选隐藏的项目。 重启电脑&#xff0c;PLSQL就卸载成功了。...

如何使用ssm实现办公OA系统0

TOC 10907ssm办公OA系统10907ssm0 第一章 绪 论 1.1背景及意义 系统管理也都将通过计算机进行整体智能化操作&#xff0c;对于办公OA系统所牵扯的管理及数据保存都是非常多的&#xff0c;例如管理员&#xff1b;主页、个人中心、公司公告管理、设备分类管理、办公设备管理、…...

IPguard与Ping32—选择合适的企业数据保护解决方案

在数字化时代&#xff0c;企业面临着各种数据安全挑战&#xff0c;选择合适的保护工具至关重要。IPguard与Ping32是两款备受关注的数据保护软件&#xff0c;但它们各自的功能和适用场景有所不同&#xff0c;企业在选择时需根据自身需求做出明智决策。 Ping32&#xff1a;全面的…...

2024 kali虚拟机安装教程,分两大步骤,图文讲解(2)

准备工作&#xff1a; 按照图文讲解&#xff08;1&#xff09;搭建好虚拟机&#xff0c;继续以下步骤 2024 kali虚拟机安装教程&#xff0c;分两大步骤&#xff0c;图文讲解&#xff08;1&#xff09;-CSDN博客 正式开始 1.开启&#xff0c;↑ ↓ 方向键&#xff0c;选择第一…...

【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem

git clone 是 Git 版本控制系统中的一个基本命令&#xff0c;用于从远程仓库复制一个完整的版本库到本地。这个命令不仅复制远程仓库中的所有文件&#xff0c;还复制仓库的历史记录&#xff0c;使得你可以在本地进行版本控制操作&#xff0c;如提交&#xff08;commit&#xff…...

基于STM32的智能家居--硬件接线

分配GPIO 1.首先分配串口通讯引脚&#xff0c;该开发板中有三组串口引脚分别分配如图所示。 2.分配SPI。 3.其他为普通GPIO口&#xff0c;B8,B9模拟IIC协议与OLED屏幕进行通讯。...

mac电脑如何删除应用程序?怎么删除苹果电脑里的软件

在使用Mac电脑的过程中&#xff0c;随着时间的推移&#xff0c;我们可能会安装大量的应用程序。然而&#xff0c;这些应用程序中有很多可能只是临时使用&#xff0c;或者已经不再需要了。这些无用的应用程序不仅占据了宝贵的硬盘空间&#xff0c;还可能拖慢Mac系统的运行速度。…...

Hive优化操作(一)

Hive SQL 优化指南 在使用 Hive 进行数据分析时&#xff0c;提高查询性能至关重要。以下是一些具体的优化策略&#xff0c;帮助我们在工作中更有效地管理和查询数据。 一、 减少数据量进行优化 1. 分区表优化 分区是一种表的子集&#xff0c;用于按某一列&#xff08;如日期…...

Vue中常用指令——(详解,并附有代码)

文章目录 一.指令合集1.0 概述1.1 插值表达式1.2 v-text/v-html1.3 v-show/ v-if1.4 v-on1.4.1 内联语句1.4.2 事件处理函数 1.5 v-bind1.6 Test1.7 v-for 一.指令合集 内容渲染指令&#xff08;v-html、v-text&#xff09;条件渲染指令&#xff08;v-show、v-if、v-else、v-e…...

redistemplate实现点赞相关功能

使用Redis的SET数据结构来存储每个实体的点赞用户ID列表&#xff0c;方便进行点赞数量的计数和用户点赞状态的检查。以下是一个小demo&#xff0c;只提供简单思路。 Service public class LikeService {Autowiredprivate RedisTemplate redisTemplate;//点赞public Long like(…...

C++ 算法学习——7.4.1 优化算法——双指针

双指针法&#xff08;Two Pointers&#xff09;是一种常用的算法技巧&#xff0c;通常用于解决数组或链表中的问题。这种技巧通过维护两个指针&#xff0c;通常分别指向数组或链表的不同位置&#xff0c;来协同解决问题。双指针法一般有两种类型&#xff1a;快慢指针和左右指针…...

镁光DDR3的命名

64M16的解释如图。 125是指一个时钟周期需要1.25ns走完&#xff0c;1us对应 1MHZ, 1ns对应1000MHZ ,那么1.25ns对应的时钟频率&#xff0c;就先用 1/1.25得到 1.25us对应的时钟频率 0.8 &#xff0c;然后再乘以1000&#xff0c;得到800就是MHZ 带宽的计算就是 800M…...

[Git] Git下载及使用 从入门到精通 详解(附下载链接)

前言 目录 Git概述 简介 下载 Git代码托管服务 Git常用命令 Git全局配置 获取Git仓库 在本地初始化一个Git仓库 从远程仓库克隆 基本概念 工作区文件状态 本地仓库操作 远程仓库操作 分支操作 标签操作 在IDEA中使用Git 在IDEA中配置Git 本地仓库操作 远程仓…...

Linux源码阅读笔记-USB驱动分析

基础层次详解 通用串行总线&#xff08;USB&#xff09;主要用于连接主机和外部设备&#xff08;协调主机和设备之间的通讯&#xff09;&#xff0c;USB 设备不能主动向主机发送数据。USB 总线采用拓扑&#xff08;树形&#xff09;&#xff0c;主机侧和设备侧的 USB 控制器&a…...

【超级详细解释】力扣每日一题 134.加油站 48. 旋转图像

134.加油站 力扣 这是一个很好的问题。这个思路其实基于一种贪心策略。我们从整个路径的油量变化来理解它&#xff0c;结合一个直观的“最低点法则”&#xff0c;来确保找到正确的起点。 问题的核心&#xff1a;油量差值的累积 对于每个加油站&#xff0c;我们有两个数组&…...

数据挖掘基本架构知识点

数据挖掘的基本架构主要包含以下几个部分&#xff1a; 一、数据获取 1. 数据源 - 可以是数据库&#xff08;如关系型数据库MySQL、Oracle等&#xff09;、文件系统&#xff08;如CSV文件、XML文件等&#xff09;、网络数据&#xff08;如网页内容、社交媒体数据&#xff09;等…...

LangChain中使用Prompt01

1.引入提示模板 from langchain.prompts import (SystemMessagePromptTemplate,AIMessagePromptTemplate,HumanMessagePromptTemplate, )2.设置系统提示 system_template_text"你是一位专业的翻译&#xff0c;能够将{input_language}翻译成{output_language}&#xff0c…...

如何使用bpmn-js实现可视化流程管理

介绍 BPMN-JS是一个流行的开源库&#xff0c;用于在Web应用程序中可视化、创建、编辑和分析BPMN&#xff08;Business Process Model and Notation&#xff0c;业务流程建模与表示法&#xff09;2.0 图。BPMN是一种国际标准的图形化语言&#xff0c;用于描述企业中的业务流程&a…...

【PostgreSQL 】实战篇——如何使用 EXPLAIN 和 ANALYZE 工具分析查询计划和性能,优化查询

在数据库管理中&#xff0c;优化查询性能是确保应用程序高效运行的关键因素之一。 随着数据量的不断增长和复杂查询的增多&#xff0c;理解查询的执行计划变得尤为重要。 PostgreSQL 提供了强大的工具 EXPLAIN 和 ANALYZE&#xff0c;帮助开发者分析查询计划和性能&#xff0…...

List、Map、Set 三个接口存取元素时,各有什么特点

List、Map、Set是Java集合框架中的三个核心接口&#xff0c;它们在存取元素时各自具有独特的特点。以下是对这三个接口存取元素特点的详细分析&#xff1a; List接口 有序性&#xff1a; List中的元素是有序的&#xff0c;它们按照插入的顺序进行排列。 可重复性&#xff1a…...

掌握 ASP.NET Web 开发:从基础到身份验证

ASP.NET 是微软开发的一个功能强大的框架&#xff0c;广泛用于构建现代化的 Web 应用程序。它支持 MVC 架构、Web API、Razor 语法&#xff0c;并提供完善的身份验证与授权机制。本文将介绍 ASP.NET 的基础知识、MVC 模式、Web API 开发、Razor 语法&#xff0c;以及如何实现身…...