Spring Boot 中的事务管理是如何工作的?

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在企业级应用开发中,事务管理是一个至关重要的部分,尤其是当你需要处理多个数据源或复杂的数据库操作时。Spring Boot 提供了一种强大而简便的方式来管理事务。理解 Spring Boot 中的事务管理工作原理,不仅能够帮助我们写出更可靠的代码,还能确保系统的一致性和可靠性。

  今天,我们将深入探讨 Spring Boot 中的事务管理机制,如何使用它来确保数据的一致性,避免数据错误或丢失。

一、什么是事务管理?

  事务管理是指通过一组操作保证数据库的原子性、一致性、隔离性和持久性(即ACID原则)。事务管理的目标是确保一组操作要么都执行成功,要么都回滚,以保证数据库处于一致性状态。

1. 事务的四大特性(ACID)

  • 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败。如果一个操作失败,事务会回滚。
  • 一致性(Consistency):事务开始之前和事务结束之后,数据库的一致性要保持。
  • 隔离性(Isolation):事务之间是独立的,一个事务的执行不应影响其他事务的执行。
  • 持久性(Durability):一旦事务提交,它所做的修改应该永久保存,即使系统崩溃也不应丢失。

二、Spring Boot 中的事务管理

在 Spring Boot 中,事务管理由 Spring Framework 提供支持。Spring 提供了两种主要的事务管理方式:

  1. 编程式事务管理(Programmatic Transaction Management):通过编程的方式显式地控制事务。
  2. 声明式事务管理(Declarative Transaction Management):通过注解或者 XML 配置,隐式地管理事务的开启、提交、回滚等操作。

1. Spring Boot 中的声明式事务管理

声明式事务管理是 Spring 最常用的事务管理方式,它通过注解的方式让事务管理变得非常简单,通常不需要手动编写事务管理的代码。

1.1 @Transactional 注解

在 Spring Boot 中,使用 @Transactional 注解可以非常方便地实现事务管理。它可以加在方法上或者类上,表示该方法或者类中的所有方法都需要进行事务管理。Spring 会自动在调用方法时开启事务,方法执行完成后提交事务,如果方法执行失败,则回滚事务。

1.2 使用 @Transactional 注解

首先,确保你的 Spring Boot 项目中已经启用了事务管理。Spring Boot 会自动根据 spring-boot-starter-data-jpaspring-boot-starter-jdbc 等依赖启用事务支持。然后,可以通过在服务层(Service)方法上使用 @Transactional 注解来进行事务管理。

示例:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional
    public void createUser(User user) {
        userRepository.save(user);
        // 在这里可以进行多个操作,Spring 会确保这些操作在同一个事务内执行
        // 如果任何操作失败,所有操作会回滚
    }
}

在这个例子中,createUser 方法使用了 @Transactional 注解。当方法执行时,Spring 会为方法开启一个事务。如果方法执行成功,事务会提交;如果方法出现异常,事务会回滚。

1.3 @Transactional 的默认行为
  • 事务的传播行为(Propagation):Spring 的事务传播行为决定了一个事务方法应该如何与另一个事务方法交互。常用的传播行为有 REQUIRED(默认)、REQUIRES_NEW 等。

  • 事务的隔离级别(Isolation):隔离级别决定了事务之间的隔离程度。常见的隔离级别有 READ_COMMITTEDREPEATABLE_READSERIALIZABLE 等。Spring 默认的隔离级别是 DEFAULT,意味着使用数据库的默认隔离级别。

  • 回滚规则(Rollback):默认情况下,Spring 会在遇到 RuntimeExceptionError 时回滚事务,而对于 CheckedException(受检异常),Spring 不会回滚事务,除非显式指定。

示例:
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public void updateUser(User user) throws Exception {
    // 更新用户信息
    userRepository.update(user);
    // 如果发生异常,事务会回滚
}
1.4 @Transactional 的参数详解
  • rollbackFor:定义哪些异常会导致事务回滚。默认情况下,Spring 仅对 RuntimeExceptionError 类型的异常进行回滚。如果想要对受检异常(CheckedException)也进行回滚,可以使用 rollbackFor 参数。

  • isolation:定义事务的隔离级别。不同的隔离级别决定了事务如何与其他并发事务交互。

  • propagation:定义事务的传播行为,决定事务如何在不同的方法之间传播。常用的传播行为有:

    • REQUIRED(默认):如果当前有事务,则加入当前事务,否则新建一个事务。
    • REQUIRES_NEW:无论当前是否有事务,都新建一个事务,挂起当前事务。
    • NESTED:如果当前有事务,则开启一个嵌套事务。

2. 编程式事务管理

编程式事务管理让开发者显式地控制事务的生命周期,包括事务的开始、提交和回滚。尽管编程式事务提供了更高的灵活性,但它的复杂度和耦合性较高,因此一般不推荐在 Spring Boot 中使用,除非在一些特殊的场景下。

2.1 编程式事务管理的实现

Spring 提供了 PlatformTransactionManager 接口来支持编程式事务管理。你可以通过它来控制事务的开始、提交和回滚。

示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

@Service
public class UserService {

    private final UserRepository userRepository;
    private final PlatformTransactionManager transactionManager;

    @Autowired
    public UserService(UserRepository userRepository, PlatformTransactionManager transactionManager) {
        this.userRepository = userRepository;
        this.transactionManager = transactionManager;
    }

    public void createUser(User user) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            userRepository.save(user);
            // 手动提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            // 异常发生时回滚事务
            transactionManager.rollback(status);
            throw e;
        }
    }
}

3. 事务传播行为

事务的传播行为决定了一个事务方法如何与另一个事务方法交互。常见的传播行为有:

  1. REQUIRED(默认):如果当前有事务,加入当前事务。如果当前没有事务,新建一个事务。
  2. REQUIRES_NEW:无论当前是否有事务,都新建一个事务,挂起当前事务。
  3. NESTED:如果当前有事务,则开启一个嵌套事务,当前事务提交或回滚时,嵌套事务也会提交或回滚。
  4. SUPPORTS:如果当前有事务,加入当前事务;如果当前没有事务,方法不在事务中执行。
  5. NOT_SUPPORTED:如果当前有事务,挂起当前事务,方法不在事务中执行。
  6. MANDATORY:当前必须有事务,若没有事务抛出异常。
  7. NEVER:当前不能有事务,如果有事务则抛出异常。

4. 事务隔离级别

事务的隔离级别决定了事务之间的隔离程度,不同的隔离级别会影响数据库中并发事务的执行方式。常见的事务隔离级别包括:

  1. DEFAULT:使用数据库默认的隔离级别。
  2. READ_UNCOMMITTED:最低级别的隔离级别,允许读取未提交的数据(脏读)。
  3. READ_COMMITTED:允许读取已提交的数据,避免脏读。
  4. REPEATABLE_READ:确保一个事务读取的数据在该事务期间不会改变(避免不可重复读)。
  5. SERIALIZABLE:最高级别的隔离级别,确保事务完全串行执行,避免所有并发问题(脏读、不可重复读、幻读)。

五、总结

Spring Boot 提供了非常强大的事务管理功能,尤其是通过 @Transactional 注解,开发者可以轻松地实现事务的管理,无论是数据持久化操作的原子性,还是对于异常的回滚,Spring 的事务管理都能提供高效且简洁的解决方案。

  • 对于常见的事务管理需求,推荐使用声明式事务管理(@Transactional 注解)。
  • 对于更复杂的场景,编程式事务管理可以提供更细粒度的控制,但通常建议尽量避免使用。

通过正确使用事务管理,我们可以确保应用的数据一致性和可靠性,提高系统的稳定性和可维护性。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值