在 Spring Boot 中使用事务

这篇具有很好参考价值的文章主要介绍了在 Spring Boot 中使用事务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

当调用使用 @Transactional 注解的方法时,Spring Boot利用事务管理器来创建或加入事务。事务管理器监视事务的生命周期,根据操作结果进行提交或回滚。

事务隔离级别

Spring Boot支持各种事务隔离级别,包括READ_UNCOMMITTED(读取未提交的数据)、READ_COMMITTED(读取已提交的数据)、REPEATABLE_READ(可重复读)、SERIALIZABLE(串行化)。这些级别确定事务如何与其他事务和底层数据交互。根据应用程序的需求选择正确的隔离级别。

@Service
public class UserService {
  @Autowired
  private UserRepository userRepository;
jj@Transactional
  public void updateUser(String username, String email) {
    User user = userRepository.findByUsername(username);
    user.setEmail(email);
    // ... other operations
  }
}

在上面的示例中,updateUser() 被标记为 @Transactional,允许Spring Boot管理事务的行为。

理解事务传播

事务行为可以根据方法的注解方式而有所不同。以下是一个关键区别:

@Transactional vs. @Transactional(propagation = Propagation.REQUIRES_NEW)

  • @Transactional 创建或加入一个事务。
  • @Transactional(propagation = Propagation.REQUIRES_NEW)
    创建一个新的事务,如果当前存在事务,则将其挂起。
@Service
public class MyService {
@Transactional
    public void methodA() {
        // ... some code here
        methodB();
        // ... some code here
    }
@Transactional(propagation = Propagation.REQUIRES_NEW)
    public void methodB() {
        // ... some code here
    }
}

在这个例子中,methodA() 调用了 methodB()。由于 REQUIRES_NEW 传播设置,当 methodB() 开始一个新的事务时,methodA() 的事务被挂起。

在同一类内处理事务

当一个 @Transactional 方法调用同一类内的另一个 @Transactional 方法时,Spring 的默认行为值得注意:

默认行为

默认情况下,Spring 使用一种“基于代理”的方法。如果一个 @Transactional 方法调用同一类内的另一个 @Transactional 方法,事务行为不会被应用。

@Service
public class MyService {
    @Autowired
    private MyService self;
ja   @Transactional
    public void methodA() {
        // ... some code here
        self.methodB();
        // ... some code here
    }
@Transactional
    public void methodB() {
        // ... some code here
    }
}

在这个例子中,methodA() 和 methodB() 都被标记为 @Transactional。然而,由于“基于代理”的方法,当从 methodA() 调用 methodB() 时,事务行为不会被应用。为了解决这个问题,可以考虑使用基于AspectJ的织入(weaving)或将 @Transactional 方法移到一个单独的类中。

跨不同Bean管理事务

当调用另一个Bean上的方法时,Spring会在目标Bean周围创建一个新的代理,使其能够管理事务行为:

@Service
public class MyService {
@Autowired
    private OtherService otherService;
@Transactional
    public void methodA() {
        // ... some code here
        otherService.methodB();
        // ... some code here
    }
}
@Service
public class OtherService {
   @Transactional
    public void methodB() {
        // ... some code here
    }
}

在这个例子中,methodA() 在一个不同的Bean(OtherService)上调用了 methodB()。Spring会在 OtherService 周围创建一个新的代理,以根据 methodA() 的传播设置应用事务行为。

处理未检查的异常

当一个 @Transactional 方法抛出未检查的异常时,Spring 默认情况下会自动回滚事务。这确保如果发生错误,事务内的数据更改不会被持久化。

@Service
@Transactional
public class UserService {
 @Autowired
  private UserRepository userRepository;
 public void updateUser(String username, String email) {
    User user = userRepository.findByUsername(username);
    if (user == null) {
      throw new RuntimeException("User not found");
    }
    user.setEmail(email);
    userRepository.save(user);
    throw new RuntimeException("Something went wrong");
  }
}

在这个例子中,updateUser() 被标记为 @Transactional 并抛出一个未检查的异常。默认情况下,事务将回滚,丢弃对用户电子邮件地址所做的更改。

自定义回滚行为

您可以使用 @Transactional 注解的 rollbackFor 或 noRollbackFor 属性来自定义回滚行为。

@Service
@Transactional(noRollbackFor = RuntimeException.class)
public class UserService { 
// ...
}

在这个例子中,我们指定 RuntimeException 不应触发回滚。这在您希望在事务内保留更改,即使发生错误时也很有用。

默认的回滚行为

默认情况下,@Transactional 方法在任何未检查的异常发生时都会回滚事务。使用 rollbackFor 或 noRollbackFor 属性来自定义此行为。

私有方法和 @Transactional

@Transactional 仅在公共方法上工作。Spring在公共方法周围创建代理以管理事务行为。私有方法对代理不可见,无法被包装在事务上下文中。

@Service
public class MyService {
   @Transactional
    public void methodA() {
        // ... some code here
        methodB();
        // ... some code here
    }
    private void methodB() {
        // ... some code here
    }
}

在这个例子中,methodA() 被标记为 @Transactional,但 methodB() 没有。要启用 methodB() 的事务行为,将其设置为公共方法,或将 @Transactional 注解移到同时调用 methodA() 和 methodB() 的方法上。

处理并发问题

Spring Boot 的 @Transactional 注解通过串行化事务提供了处理并发问题的机制。默认的隔离级别通过确保事务不相互干扰来防止大多数并发问题。

@Service
public class UserService {
  @Autowired
  private UserRepository userRepository;
 @Transactional
  public void updateUser(String username, String email) {
    User user = userRepository.findByUsername(username);
    user.setEmail(email);
    // ... other operations
  }
}

在这个例子中,updateUser() 被标记为 @Transactional,并且Spring确保当多个线程同时尝试修改同一用户的电子邮件地址时,事务是串行化的。这可以防止数据不一致和竞态条件。

请记住,Spring 中 @Transactional 使用的默认隔离级别是 Isolation.DEFAULT,它与底层数据源的默认值一致。这通常导致"读已提交"的隔离级别,适用于大多数数据库。

精通 @Transactional 对于在Spring Boot应用程序中进行有效的事务管理非常重要。文章来源地址https://www.toymoban.com/news/detail-824442.html

到了这里,关于在 Spring Boot 中使用事务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring Boot】使用XML配置文件实现数据库操作(一)

    SQL映射文件就是我们通常说的mapper.xml配置文件,主要实现SQL语句的配置和映射,同时实现Java的POJO对象与数据库中的表和字段进行映射关联的功能。 1.1 mapper.xml的结构 下面就来详细介绍mapper.xml文件的结构。首先看一个完整的mapper.xml示例:

    2024年02月10日
    浏览(45)
  • Spring Boot使用jasypt处理数据库账号密码等数据加密问题

    在我们业务场景中,项目中的application.yml 配置文件比如数据库账号密码,的各种链接的username,password的值都是明文的,存在一定的安全隐患,可以使用jasypt 加密框架的方式进行明文加密,进而使得我们项目更加安全 注意这里排除了mybatis-plus的包可能是项目中有冲突依赖,

    2024年02月06日
    浏览(42)
  • 【Spring Boot】Spring Boot 配置 Hikari 数据库连接池

    数据库连接池是一个提高程序与数据库的连接的优化,连接池它主要作用是提高性能、节省资源、控制连接数、连接管理等操作; 程序中的线程池与之同理,都是为了优化、提高性能。

    2024年02月11日
    浏览(35)
  • 【Spring Boot】通过AOP拦截Spring Boot日志并将其存入数据库

    在软件开发中,常常需要记录系统运行时的日志。日志记录有助于排查系统问题、优化系统性能、监控操作行为等。本文将介绍如何使用Spring Boot和AOP技术实现拦截系统日志并保存到数据库中的功能。 本文将通过以下步骤实现拦截系统日志并保存到数据库中的功能: 配置数据

    2024年02月10日
    浏览(36)
  • Spring Boot:数据库的整合

    在 Spring Boot :Web开发之视图模板技术的整合 文章中,介绍了 Spring Boot 整合视图模板技术。然而,仅仅整合视图模板技术可能还不能满足所有业务需求,因此还需要进一步扩展 Spring MVC 的默认配置。 简单补充说明 : 扩展 Spring Boot 中的 Spring MVC 默认配置通常涉及实现 WebMvcC

    2024年04月13日
    浏览(36)
  • Spring Boot项目使用 jasypt 加密组件进行加密(例如:数据库、服务的Key、等等进行加密)

    🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝 🍓 更多文章请点击 密码配置项都不加密? 想啥呢? 一

    2024年02月07日
    浏览(41)
  • 【Spring Boot】数据库持久层框架MyBatis — Spring Boot构建MyBatis应用程序

    Spring Boot是用于快速构建Spring应用程序的框架。MyBatis是一种Java持久化框架,可以帮助开发人员轻松地管理数据库。将Spring Boot与MyBatis结合使用可以使开发人员更容易地创建和管理数据库应用程序。 以下是使用Spring Boot构建MyBatis应用程序的步骤: 添加MyBatis依赖项:在项目的

    2024年02月10日
    浏览(42)
  • Spring Boot对接Oracle数据库

    最近学习了Oracle数据库,那么如何使用Spring Boot和MyBatis Plus对接Oracle数据库呢? 这就有了这篇随记,具体流程如下 创建一个空的Maven工程,导入如下依赖: tips:这里碰到一个坑,我本机适用的Oracle数据库版本是11g XE,所以要使用的驱动为ojdbc5/ojdbc6,不然连接老会失败。 在配

    2024年02月09日
    浏览(35)
  • 使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库

    记录 :415 场景 :使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库。 版本 :JDK 1.8,Spring Boot 2.6.3,dynamic-datasource-spring-boot-starter-3.3.2,mybatis-3.5.9。 源码 :https://github.com/baomidou/dynamic-datasource-spring-boot-starter dynamic-datasource-spring-boot-starter :一个基于springboot的快

    2023年04月19日
    浏览(32)
  • Spring Boot如何访问不同的数据库

            在Spring Boot应用中连接多个数据库或数据源可以使用多种方式,下面介绍两种常用的方法: 1、使用Spring Boot官方支持的多数据源配置         spring boot提供了官方支持的多数据源配置,可以简单地配置和管理多个数据源。         需要在application.properties文件中

    2024年02月13日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包