无痛事务管理:Spring中的@Transactional和相关注解完全解析

本文主要是介绍无痛事务管理:Spring中的@Transactional和相关注解完全解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

无痛事务管理:Spring中的@Transactional和相关注解完全解析

  • 前言
  • 事务管理基础
    • 为什么需要事务管理?
    • Spring框架中的事务管理优势:
  • @Transactional注解的奥秘
    • **1. 如何使用@Transactional注解来声明事务?**
    • **2. 支持的传播行为(Propagation)和隔离级别(Isolation)**
    • **3. 事务的超时、只读属性和回滚条件**
  • @TransactionManagement和@EnableTransactionManagement
    • **1. @TransactionManagement注解的作用和使用方式**
    • **2. @EnableTransactionManagement注解的目的和配置**
    • **3. 在不同的Spring配置方式中如何启用事务管理**
    • 4、springboot不需要使用这两个注解
  • 嵌套事务
    • **1. 什么是嵌套事务?**
    • **2. 如何在Spring中实现嵌套事务?**
    • **3. 注意事项和最佳实践**
  • 事务传播行为
  • 事务管理的异常处理
    • **1. 默认异常处理策略**:
    • **2. 自定义异常处理策略**:
    • **3. 回滚条件的组合**:
    • **4. 不回滚异常**:
    • **5. 延迟异常处理**:

前言

在软件开发的世界里,事务管理是一个至关重要的话题。它就像是保险丝,一旦出了问题,整个应用程序可能都会崩溃。在这篇博客中,我们将探索Spring框架中的事务管理,特别关注@Transactional@TransactionManagement@EnableTransactionManagement这些神奇的注解,它们如何帮助我们轻松地管理事务,确保数据的一致性和完整性。

事务管理基础

事务是指一组操作或任务,它们被视为一个不可分割的单元,要么全部成功执行,要么全部失败回滚,保持数据的一致性和完整性。事务管理是一种机制,用于确保在数据库操作中的事务能够按照预期的方式执行,不会发生数据不一致或损坏。

为什么需要事务管理?

  1. 数据一致性:在多个数据库操作中,如果其中一个操作失败,事务管理可以确保回滚到操作前的状态,以维护数据一致性。
  2. 数据完整性:通过事务管理,可以确保数据在事务结束时处于完整的状态,不会出现中间状态的数据。
  3. 并发控制:多个用户或进程可能同时访问数据库,事务管理可以协调并发访问,避免数据竞争和冲突。

Spring框架中的事务管理优势:

Spring提供了强大的事务管理支持,具有以下优势:

  1. 声明式事务管理:Spring允许通过注解或XML配置声明式事务管理,而不需要显式编写事务管理代码。
  2. 多种事务管理器:Spring支持不同的事务管理器,如JDBC、Hibernate、JTA等,使其适用于各种数据访问技术。
  3. 编程式事务管理:除了声明式事务,Spring还允许通过编程方式管理事务,以实现更细粒度的控制。
  4. 异常处理:Spring允许在事务中处理异常,可以根据需要回滚或提交事务。
  5. 嵌套事务:Spring支持嵌套事务,允许在一个事务中调用另一个事务,保持数据一致性。

总之,Spring框架中的事务管理提供了灵活、简化和可维护的方式来处理数据库事务,有助于提高应用程序的可靠性和性能。同时,使用Spring的事务管理还使得代码更加清晰,因为它要求在事务管理方面有良好的注释和文档。

@Transactional注解的奥秘

@Transactional注解是Spring框架中用于声明事务的关键注解之一。它可以用于方法级别或类级别,用于指示哪些方法需要事务管理。下面是关于@Transactional注解的详细信息:

1. 如何使用@Transactional注解来声明事务?

在Spring中,你可以将@Transactional注解应用于方法级别,以指示方法需要在事务管理下执行。以下是一个简单的示例:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class MyService {@Transactionalpublic void performDatabaseOperation() {// 执行数据库操作}
}

在上面的示例中,performDatabaseOperation方法被标记为@Transactional,因此它将在事务管理下执行。

2. 支持的传播行为(Propagation)和隔离级别(Isolation)

@Transactional注解支持多种传播行为和隔离级别,它们用于定义事务的行为方式:

  • 传播行为(Propagation):用于定义当方法被调用时,当前方法的事务如何与新的事务互动。一些常见的传播行为包括REQUIRED(默认值,如果没有事务,创建一个新事务;如果已经存在事务,则加入该事务)和REQUIRES_NEW(创建一个新事务,如果已经存在事务,则挂起当前事务并开始一个新事务)等。

  • 隔离级别(Isolation):用于定义事务的隔离级别,即多个事务之间的相互影响程度。常见的隔离级别包括READ_COMMITTED(默认值,允许读已提交的数据)和SERIALIZABLE(最高隔离级别,确保事务不会相互干扰)等。

你可以使用@Transactional注解的propagationisolation属性来配置传播行为和隔离级别,例如:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void performDatabaseOperation() {// 执行数据库操作
}

3. 事务的超时、只读属性和回滚条件

  • 超时属性:你可以使用timeout属性来定义事务的超时时间,单位为秒。如果事务在规定时间内未完成,它将被自动回滚。例如:@Transactional(timeout = 30)表示事务的超时时间为30秒。

  • 只读属性:通过设置readOnly属性为true,可以告诉Spring该事务只读,不会修改数据。这可以提高事务的性能。例如:@Transactional(readOnly = true)

  • 回滚条件:你可以使用rollbackFornoRollbackFor属性来定义在何种异常情况下事务应该回滚或不回滚。例如:

@Transactional(rollbackFor = {CustomException.class, AnotherCustomException.class})
public void performDatabaseOperation() {// 执行数据库操作,可能会抛出CustomException或AnotherCustomException
}

总之,@Transactional注解提供了丰富的选项,允许你灵活地配置事务的行为,包括传播行为、隔离级别、超时、只读属性和回滚条件,以满足不同的业务需求。同时,为了满足你的要求,务必在代码中添加相应的注释。

@TransactionManagement和@EnableTransactionManagement

在Spring中,事务管理可以通过两种方式启用:使用@TransactionManagement注解和使用@EnableTransactionManagement注解。让我分别解释它们的作用和使用方式:

1. @TransactionManagement注解的作用和使用方式

@TransactionManagement注解用于指示一个类具有事务管理的能力,但通常不直接在代码中使用,而是与<tx:annotation-driven>@EnableTransactionManagement结合使用。它的作用是启用基于注解的事务管理。

示例使用方式:

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;@Component
@EnableTransactionManagement
public class TransactionConfig implements TransactionManagementConfigurer {@Overridepublic PlatformTransactionManager annotationDrivenTransactionManager() {return myTransactionManager(); // 返回配置的事务管理器}// 配置自定义的事务管理器public PlatformTransactionManager myTransactionManager() {// 配置并返回事务管理器}
}

上述示例中,通过在一个@Component类上添加@EnableTransactionManagement注解,并实现TransactionManagementConfigurer接口,你可以配置自定义的事务管理器并启用基于注解的事务管理。

2. @EnableTransactionManagement注解的目的和配置

@EnableTransactionManagement注解用于启用Spring的事务管理功能。通常,它与@Configuration注解一起使用,以确保在配置类中启用事务管理。

示例使用方式:

import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration
@EnableTransactionManagement
public class AppConfig {// 其他配置
}

通过在配置类上添加@EnableTransactionManagement注解,你可以启用Spring的事务管理功能,而无需显式实现TransactionManagementConfigurer接口。

3. 在不同的Spring配置方式中如何启用事务管理

在Spring中,可以使用以下几种方式启用事务管理:

  • XML配置方式:通过在Spring的XML配置文件中添加<tx:annotation-driven>元素,可以启用基于注解的事务管理。
<beans xmlns="http://www.springframework.org/schema/beans"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/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><tx:annotation-driven/><!-- 配置数据源、事务管理器等其他相关配置 -->
</beans>
  • Java配置方式:通过在Java配置类上添加@EnableTransactionManagement注解,可以启用基于注解的事务管理。
@Configuration
@EnableTransactionManagement
public class AppConfig {// 其他配置
}
  • @TransactionManagement注解方式:如前面提到的,你可以使用@TransactionManagement注解和TransactionManagementConfigurer接口来配置事务管理。

总之,Spring提供了多种方式来启用事务管理,你可以根据项目的需求选择合适的方式。在任何一种方式下,都需要确保配置了事务管理器和其他相关的事务配置。同时,记得在代码中添加@Transactional注解以声明事务。在每种方式下,务必在代码中添加相应的注释以满足你的要求。

4、springboot不需要使用这两个注解

在Spring Boot项目中,事务管理通常更加简化和自动化,因此你通常不需要显式配置@TransactionManagement注解或<tx:annotation-driven>元素。Spring Boot已经为你预配置了很多事务相关的设置,包括事务管理器的创建和@EnableTransactionManagement的启用。

以下是在Spring Boot项目中使用事务管理的一般步骤:

  1. 确保你的Spring Boot应用依赖中包含了适当的数据源(如HikariCP、Tomcat JDBC等)和Spring Boot Starter Data JPA、Spring Boot Starter JDBC等。

  2. 在Spring Boot的主应用程序类上添加@SpringBootApplication注解或类似的启动注解。

  3. 在需要事务管理的方法上,使用@Transactional注解来声明事务。Spring Boot会自动扫描并启用基于注解的事务管理。

示例:

@Service
public class MyService {@Autowiredprivate MyRepository myRepository;@Transactionalpublic void performDatabaseOperation() {// 执行数据库操作,自动使用Spring Boot配置的事务管理器}
}
  1. 确保Spring Boot的配置文件(application.properties或application.yml)中包含了适当的数据源配置,如数据库连接URL、用户名、密码等。

总之,Spring Boot项目中的事务管理通常是自动配置的,你只需在需要的方法上添加@Transactional注解即可。在大多数情况下,不需要显式配置@TransactionManagement<tx:annotation-driven>。但务必确保你的Spring Boot应用的依赖和配置正确,以便正确启用事务管理。

嵌套事务

1. 什么是嵌套事务?

嵌套事务是指一个事务内部包含了另一个事务,也就是内部事务是外部事务的一部分。在嵌套事务中,内部事务可以独立地提交或回滚,但它的提交或回滚不会立即影响外部事务,只有在外部事务提交时才会被真正影响。

嵌套事务常常用于以下情况:

  • 在一个方法内部调用多个方法,每个方法都需要独立的事务。
  • 在一个事务中处理多个数据库或资源的操作,需要对每个资源都使用独立的事务。
  • 需要将某个操作分解为多个步骤,每个步骤都有独立的事务。

2. 如何在Spring中实现嵌套事务?

在Spring中,你可以使用@Transactional注解来实现嵌套事务。要启用嵌套事务,可以使用Propagation.NESTED传播行为。以下是示例:

import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;@Service
public class MyService {@Autowiredprivate MyRepository myRepository;@Transactional(propagation = Propagation.REQUIRED)public void outerTransaction() {// 外部事务逻辑myRepository.saveData();innerTransaction(); // 调用内部事务方法}@Transactional(propagation = Propagation.NESTED)public void innerTransaction() {// 内部事务逻辑myRepository.updateData();}
}

在上述示例中,outerTransaction方法使用Propagation.REQUIRED定义了外部事务,而innerTransaction方法使用Propagation.NESTED定义了内部事务。当outerTransaction被调用时,它会创建一个外部事务,然后调用innerTransaction,内部事务会嵌套在外部事务中。如果内部事务成功完成,但外部事务失败回滚,内部事务的修改将保留。只有当外部事务成功提交时,内部事务的修改才会永久保存。

3. 注意事项和最佳实践

在使用嵌套事务时,需要考虑一些注意事项和最佳实践:

  • 嵌套事务通常是与数据库事务一起使用的,因此确保数据库引擎支持嵌套事务。

  • 了解事务的传播行为,确保使用合适的传播行为来达到期望的事务行为。

  • 谨慎使用嵌套事务,只在需要的情况下使用。过多的嵌套事务可能会导致复杂性和性能问题。

  • 考虑异常处理策略,特别是在内部事务中。你可以使用@Transactional注解的rollbackFor属性来定义哪些异常会导致事务回滚。

  • 测试嵌套事务的行为,确保它们按预期工作。使用单元测试来验证嵌套事务的正确性。

总之,嵌套事务是一种强大的工具,可以用于处理复杂的事务场景,但需要谨慎使用,确保合适的传播行为和异常处理策略。在Spring中,使用@Transactional注解来管理嵌套事务是一种方便的方式。

事务传播行为

Spring框架提供了不同的事务传播行为,每种传播行为都有其独特的应用场景和影响。以下是常见的事务传播行为示例以及它们的应用场景和影响:

  1. REQUIRED(默认)
    • 应用场景:这是最常见的传播行为,也是默认的传播行为。如果当前方法没有事务,它会创建一个新的事务;如果当前方法已经在一个事务中,它将加入该事务。
    • 影响:如果外部方法有事务,内部方法会在外部事务中运行;如果外部方法没有事务,内部方法会创建一个新事务。如果内部方法失败回滚,外部方法也会回滚。
@Transactional(propagation = Propagation.REQUIRED)
public void methodWithRequiredPropagation() {// ...
}
  1. REQUIRES_NEW
    • 应用场景:无论外部方法是否有事务,内部方法总是创建一个新的事务,而不是加入外部事务。适用于内部操作需要独立事务的情况,即使外部事务回滚,内部事务也不受影响。
    • 影响:内部方法总是会创建一个新事务,与外部事务完全独立。如果内部事务失败回滚,只会影响内部事务,而不会影响外部事务。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodWithRequiresNewPropagation() {// ...
}
  1. SUPPORTS
    • 应用场景:内部方法会尝试加入外部事务,如果外部方法有事务,内部方法就在外部事务中运行;如果外部方法没有事务,内部方法就以非事务方式运行。
    • 影响:内部方法不会创建新事务,它将根据外部事务的存在与否来确定运行方式。
@Transactional(propagation = Propagation.SUPPORTS)
public void methodWithSupportsPropagation() {// ...
}
  1. NOT_SUPPORTED
    • 应用场景:无论外部方法是否有事务,内部方法都会以非事务方式运行,即使外部事务存在也会将其挂起。
    • 影响:内部方法不会加入外部事务,如果外部方法有事务,内部方法会将其挂起。
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void methodWithNotSupportedPropagation() {// ...
}
  1. NEVER
    • 应用场景:内部方法必须以非事务方式运行,如果外部方法有事务,内部方法会抛出异常。
    • 影响:内部方法不会加入外部事务,如果外部方法有事务,内部方法会抛出异常。
@Transactional(propagation = Propagation.NEVER)
public void methodWithNeverPropagation() {// ...
}
  1. MANDATORY
    • 应用场景:内部方法必须在外部事务中运行,如果外部方法没有事务,内部方法会抛出异常。
    • 影响:内部方法会加入外部事务,如果外部方法没有事务,内部方法会抛出异常。
@Transactional(propagation = Propagation.MANDATORY)
public void methodWithMandatoryPropagation() {// ...
}

这些事务传播行为提供了灵活的方式来控制事务的嵌套和运行方式,根据不同的业务需求选择适当的传播行为。务必根据具体情况谨慎选择传播行为,以确保事务行为符合业务逻辑。

事务管理的异常处理

在事务管理中,异常处理策略是非常重要的,它们用于定义当事务中发生异常时的行为。Spring提供了灵活的异常处理策略,可以帮助你控制事务的回滚和提交行为。

以下是事务中的异常处理策略以及如何自定义异常和回滚:

1. 默认异常处理策略

  • 默认情况下,Spring事务管理器会捕获RuntimeException及其子类以及Error,然后回滚事务。这意味着如果在事务中抛出RuntimeExceptionError,事务将自动回滚。
@Transactional
public void myMethod() {// 在方法中抛出RuntimeException或Error会导致事务回滚
}

2. 自定义异常处理策略

你可以通过配置@Transactional注解的rollbackFor属性来自定义异常处理策略。这允许你指定哪些异常会触发事务回滚。例如,你可以定义一个自定义异常类,并将其列入回滚异常列表:

@Transactional(rollbackFor = MyCustomException.class)
public void myMethod() throws MyCustomException {// 在方法中抛出MyCustomException会导致事务回滚
}

3. 回滚条件的组合

你还可以组合多个异常类来定义回滚条件,例如:

@Transactional(rollbackFor = {MyCustomException.class, AnotherCustomException.class})
public void myMethod() throws MyCustomException, AnotherCustomException {// 在方法中抛出MyCustomException或AnotherCustomException会导致事务回滚
}

这样,只要抛出了MyCustomExceptionAnotherCustomException中的任何一个异常,事务都会回滚。

4. 不回滚异常

如果你希望某些异常不导致事务回滚,可以使用noRollbackFor属性。例如:

@Transactional(noRollbackFor = MyCustomException.class)
public void myMethod() throws MyCustomException {// 在方法中抛出MyCustomException不会导致事务回滚
}

5. 延迟异常处理

有时,你可能希望捕获异常但不立即回滚事务,而是在方法内部进行特定处理后再决定是否回滚。这可以通过捕获异常并手动调用setRollbackOnly()来实现:

@Transactional
public void myMethod() {try {// 业务逻辑,可能会抛出异常} catch (MyCustomException e) {// 处理异常,然后根据条件决定是否回滚if (shouldRollback) {TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();}}
}

总之,事务中的异常处理策略允许你灵活地控制事务的回滚和提交行为。你可以根据具体需求定义哪些异常会导致事务回滚,以及哪些异常不会。同时,你还可以通过捕获异常后手动调用setRollbackOnly()来延迟处理异常。这些策略有助于确保事务在出现异常情况时能够按照期望的方式进行管理。

这篇关于无痛事务管理:Spring中的@Transactional和相关注解完全解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

HDU 2159 二维完全背包

FATE 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能