SpringBoot 2项目中,serviceA的方法中调用了serviceB的方法能触发事务吗

需求描述

在一个Spring Boot 2.x项目中,有一个需求是在serviceAmethod1方法中执行两个数据库操作,并在其中的某一步调用了serviceBmethod2,而method2也包含了数据库操作。

如果在这个过程中发生了异常,希望能够确保所有的数据库操作都能够回滚,以保持数据的一致性。该如何在代码中实现这个需求?


正文

先上结论:method1method2都加上 @Transactional注解

当在method1方法上添加@Transactional注解时,该方法及其内部的数据库操作将在一个事务中执行。如果在方法执行过程中抛出异常,Spring会回滚整个事务,包括method1方法中的数据库操作。

method1方法中调用serviceBmethod2时,如果method2方法也被标记为@Transactional,并且抛出了异常,整个事务将回滚,包括method1中的数据库操作和method2中的数据库操作。

事务的回滚是针对整个事务范围的,跨方法调用的情况同样适用。如果在任何被@Transactional标记的方法中抛出异常,Spring会回滚整个事务,确保所有数据库操作的一致性。

1、serviceAmethod1方法上添加@Transactional注解:

java 复制代码
@Service
public class ServiceA {

    @Autowired
    private ServiceB serviceB;

    @Transactional
    public void method1() {
        // 第一个数据库操作

        // 调用另一个Service的@Transactional方法
        serviceB.method2();

        // 第二个数据库操作

        // 如果发生异常,整个事务将回滚
    }
}

使用@Transactional注解的方法,如果在执行过程中发生异常,Spring会自动回滚整个事务。

2、serviceBmethod2方法上同样添加@Transactional注解:

java 复制代码
@Service
public class ServiceB {

    @Transactional
    public void method2() {
        // 第三个数据库操作

        // 如果发生异常,整个事务将回滚
    }
}

method2需要在方法上throws异常出去吗?

Spring默认会将未经检查的异常视为回滚原因,并触发事务回滚,无需在方法签名中声明。

如果抛出的是未经检查的异常(继承自RuntimeExceptionError),你不需要在method2的方法签名中使用throws声明。

如果发生的异常是受检查的异常(继承自Exception),你可能需要根据实际情况调整代码以处理这些异常。

示例代码:

java 复制代码
@Service
public class ServiceB {

    @Transactional(rollbackFor = XiaodouException.class)
    public void method2() throws YourCheckedException {
        // 操作数据库3

        // 抛出自定义,Spring会回滚事务
        throw new XiaodouException("Something went wrong in method2");
    }
}

额外注意事项

1、确保Spring Boot应用开启了事务管理

在项目启动类上添加@EnableTransactionManagement注解,以启用Spring的事务管理功能。

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@EnableTransactionManagement
public class XiaodouApplication {

    public static void main(String[] args) {
        SpringApplication.run(XiaodouApplication.class, args);
    }
}

2、数据库的配置需要在application.yml文件中添加,参考配置如下

yml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xiaodoudatabase # 数据库密码
    username: root # 数据库登录用户名
    password: 123456 # 数据库密码
    driver-class-name: com.mysql.cj.jdbc.Driver # 数据库驱动
相关推荐
逻辑驱动的ken1 小时前
Java高频面试场景题25
java·开发语言·深度学习·面试·职场和发展
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第32题:Java的异常处理机制是什么
java·开发语言·后端·面试
ltl2 小时前
Softmax 与概率分布:从分数到选择的桥
后端
刀法如飞3 小时前
Claude Code Skills 推荐:2026年最值得安装的10个AI技能
前端·后端·ai编程
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ3 小时前
通过java后端代码来实现给word内容补充格式文本内容控件,以及 设置控件的标记和标题
java·c#·word
無限進步D4 小时前
Java 面向对象高级 接口
java·开发语言
IT_陈寒4 小时前
Vite热更新失效?你可能漏了这个小细节
前端·人工智能·后端
逸Y 仙X5 小时前
文章二十七:ElasticSearch ES查询模板(Search Template)高效复用实战
java·大数据·数据库·elasticsearch·搜索引擎·全文检索
二哈赛车手5 小时前
新人笔记---Spring AI的Advisor以及其底层机制讲解(涉及源码),包含一些遇见的Spring AI的Advisor缺陷问题的解决方案
java·人工智能·spring boot·笔记·spring