Spring Boot 事务详解(事务传播行为、事务属性)

2025-05-21 02:50

本文主要是介绍Spring Boot 事务详解(事务传播行为、事务属性),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringBoot事务详解(事务传播行为、事务属性)》SpringBoot提供了强大的事务管理功能,通过@Transactional注解可以方便地配置事务的传播行为和属性,本文将详细介绍Spr...

Spring Boot 事务详解

引言

在现代应用程序中,事务管理是确保数据一致性和完整性的重要机制。Spring Boot 提供了强大的事务管理功能,使得开发者可以轻松地定义和管理事务。本文将详细介绍 Spring Boot 中的事务管理,包括事务传播行为、事务属性以及声明式和编程式事务管理。

声明式事务管理

声明式事务管理是通过注解的方式来管理事务,最常用的注解是 @Transactional。这种方式简单直观,适合大多数场景。

示例

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
    @Transactional
    public void createUser(User user) {
        // 数据库操作
    }
}

编程式事务管理

编程式事务管理是通过编程的方式来手动控制事务,通常使用 PlatformTransactionManagerTransactionTemplate

示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Service
public class UserService {
    @Autowired
    private PlatformTransactionManager transactionManager;
    public void createUser(User user) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setName("createUserTransaction");
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            // 数据库操作
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw e;
        }
    }
}

事务传播行为

事务传播行为定义了当一个事务方法调用另一个事务方法时,事务如何传播。Spring 提供了多种传播行为,可以通过 @Transactional 注解进行配置。以下是 Spring 支持的传播行为及其使用场景:

1. REQUIRED

定义:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

使用场景:大多数业务操作都使用该传播行为,因为它确保了调用链上的所有操作都在同一个事务中。

示例

@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
    // 业务逻辑
}

事务传播示意图

+--------+              +--------+
|  方法A  |              |  方法B  |
|        |--------------->     编程   |
|        | 传播事务 T1    |        |
+--------+              +--------+

2. SUPPORTS

定义:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。

使用场景:适用于可选的事务操作,例如只读查询。

示例

@Transactional(propagation = Propagation.MANDATORY)
public void methodC() {
    // 业务逻辑
}

事务php传播示意图

+--------+              +--------+
|  方法A  |              |  方法C  |
|        |--------------->        |
|        | 传播事务 T1    |        |
+--------+              +--------+

3. MANDATORY

定义:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

使用场景:用于强制要求在事务环境中执行的方法。

示例

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodD() {
    // 业务逻辑
}

事务传播示意图

+--------+              +--------+
|  方法A  |              |  方法C  |
|        |--------------->        |
|        | 传播事务 T1    |        |
+--------+              +--------+

4. REQUIRES_NEW

定义:创建一个新的事务,如果当前存在事务,则将当前事务挂起。

使用场景:适用于必须在一个新事务中执行的操作,例如独立的日志记录。

示例

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodD() {
    // 业务逻辑
}

事务传播示意图

+--------+              +--------+
|  方法A  |              |  方法D  |
|        |------------->|        |
| 挂起事务 T1           | 创建事务 T2 |
+--------+              +--------+

5. NOT_SUPPORTED

定义:以非事务方式执行操作,如果当前存在事务,则将当前事务挂起。

使用场景:适用于不需要事务的操作,例如批量数据处理。

示例

@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void methodE() {
    // 业务逻辑
}

事务传播示意图

+--------+              +--------+
|  方法A  |              |  方法E  |
|        |------------->|    www.chinasem.cn;    |
| 挂起事务 T1           | 非事务执行 |
+--------+              +--------+

6. NEVER

定义:以非事务方式执行,如果当前存在事务,则抛出异常。

使用场景:用于强制要求以非事务方式执行的方法。

示例

@Transactional(propagation = Propagation.NEVER)
public void methodF() {
    // 业务逻辑
}

事务传播示意图

+--------+              +--------+
|  方法A  |              |  方法F  |
|        |------------->|        |
|        | 如果存在事务 T1,抛异常 |
+--------+              +--------+

7. NESTED

定义:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则行为与 REQUIRED 类似。

使用场景:适用于需要在主事务中执行的子事务,例如复杂的数据库操作。

示例

@Transactional(propagation = Propagation.NESTED)
public void methodG() {
    // 业务逻辑
}

事务传播示意图

+--------+              +--------+
|  方法A  |              |  方法G  |
|        |------------->|        |
| 事务 Tjavascript1             | 嵌套事务 T1.1 |
+--------+              +--------+

事务失效情况

Spring Boot 通过 Spring 框架的事务管理模块来支持事务操作。事务管理在 Spring Boot 中通常是通过 @Transactional 注解来实现的。以下是一些常见的事务失效情况:

1. 未捕获异常

如果一个事务方法中发生了未捕获的异常,并且异常未被处理或传播到事务边界之外,那么事务会失效,所有的数据库操作会回滚。

2. 非受检异常

默认情况下,Spring 对非受检异常(RuntimeException 或其子类)进行回滚处理,这意味着当事务方法中抛出这些异常时,事务会回滚。

3. 事务传播属性设置不当

如果在多个事务之间存在事务嵌套,且事务传播属性配置不正确,可能导致事务失效。特别是在方法内部调用有 @Transactional 注解的方法时要特别注意。

4. 多数据源的事务管理

如果在使用多数据源时,事务管理没有正确配置或者存在多个 @Transactional 注解时,可能会导致事务失效。

5. 跨方法调用事务问题

如果一个事务方法内部调用另一个方法,而这个被调用的方法没有 @Transactional 注解,这种情况下外层事务可能会失效。

6. 事务在非公开方法中失效

如果 @Transactional 注解标注在私有方法上或者非 public 方法上,事务也会失效。

7. 使用this调用事务方法

Spring 事务是通过代理对象来控制的,只有通过代理对象的方法调用才会应用事务管理的相关规则。当使用 this 直接调用时,是绕过了 Spring 的代理机制,因此不会应用事务设置。

回滚条件

1. 自动回滚事务

  • 抛出未检查异常(RuntimeException 及其子类),例如:NullPointerException 等。

2. 不会自动回滚

  • 默认情况下,检查异常(如 IOExceptionSQLException 等)不会触发回滚。可以通过 @Transactional 注解的 rollbackFor 属性配置回滚:

示例

@Transactional(rollbackFor = IOException.class)
public void methodH() {
    // 业务逻辑
}

事务属性

除了传播行为,Spring 还提供了一些其他事务属性,可以通过 @Transactional 注解进行配置。

1. 隔离级别

隔离级别定义了一个事务与其他事务隔离的程度。Spring 支持以下几种隔离级别:编程

  • DEFAULT:使用数据库默认的隔离级别。
  • READ_UNCOMMITTED:读未提交的变更。
  • READ_COMMITTED:读已提交的变更。
  • REPEATABLE_READ:可重复读。
  • SERIALIZABLE:串行化。

示例

@Transactional(isolation = Isolation.READ_COMMITTED)
public void methodI() {
    // 业务逻辑
}

2. 事务超时

事务超时定义了事务在回滚之前可以运行的最长时间(以秒为单位)。

示例

@Transactional(timeout = 30)
public void methodJ() {
    // 业务逻辑
}

3. 只读事务

只读事务用于优化只读操作。设置为只读的事务可以提示数据库引擎进行某些优化。

示例

@Transactional(readOnly = true)
public void methodK() {
    // 业务逻辑
}

4. 回滚规则

通过 rollbackFornoRollbackFor 属性可以指定哪些异常会触发事务回滚,哪些不会。

示例

@Transactional(rollbackFor = Exception.class)
public void methodL() {
    // 业务逻辑
}

常见面试题解析

1. 什么是事务传播行为?Spring 提供了哪些事务传播行为?

:事务传播行为定义了当一个事务方法调用另一个事务方法时,事务如何传播。Spring 提供了以下事务传播行为:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。

2. 如何配置事务的隔离级别?Spring 提供了哪些隔离级别?

:可以通过 @Transactional 注解的 isolation 属性配置事务的隔离级别。Spring 提供了以下隔离级别:DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE。

3. 什么是只读事务?如何配置?

:只读事务用于优化只读操作。可以通过 @Transactional 注解的 readOnly 属性配置只读事务。例如:@Transactional(readOnly = true)

4. 如何配置事务的超时时间?

:可以通过 @Transactional 注解的 timeout 属性配置事务的超时时间(以秒为单位)。例如:@Transactional(timeout = 30)

5. 如何指定哪些异常会触发事务回滚?

:可以通过 @Transactional 注解的 rollbackFor 属性指定哪些异常会触发事务回滚。例如:@Transactional(rollbackFor = Exception.class)

总结

Spring Boot 提供了强大的事务管理功能,通过 @Transactional 注解可以方便地配置事务的传播行为和属性。理解和合理应用这些配置,可以有效地提高应用程序的数据一致性和完整性。

到此这篇关于Spring Boot 事务详解(事务传播行为、事务属性)的文章就介绍到这了,更多相关Spring Boot 事务内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Spring Boot 事务详解(事务传播行为、事务属性)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154700

相关文章

Java 正则表达式的使用实战案例

《Java正则表达式的使用实战案例》本文详细介绍了Java正则表达式的使用方法,涵盖语法细节、核心类方法、高级特性及实战案例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、正则表达式语法详解1. 基础字符匹配2. 字符类([]定义)3. 量词(控制匹配次数)4. 边

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Java中的stream流分组示例详解

《Java中的stream流分组示例详解》Java8StreamAPI以函数式风格处理集合数据,支持分组、统计等操作,可按单/多字段分组,使用String、Map.Entry或Java16record... 目录什么是stream流1、根据某个字段分组2、按多个字段分组(组合分组)1、方法一:使用 Stri

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键