StackTraces
Spring Boot已验证

Spring Boot 报 No bean named transactionManager

@debug_master27 天前更新阅读 6 min00

@Transactional 默认按名称 transactionManager 查找事务管理器 Bean。只配了数据源却把事务自动配置 exclude 掉、或自动装配根本没触发,就会抛 NoSuchBeanDefinitionException: No bean named 'transactionManager' available——这是装配期就爆掉的硬报错,不是静默失效。

Issue & Env(案发现场与环境)

  • JDK 版本:OpenJDK 17 / 21
  • Spring Boot 版本:2.7.x / 3.x
  • 依赖场景:使用 MyBatis / JDBC,或自定义数据源配置类但未注册配套事务管理器。
  • 触发背景:应用启动一切正常,但在接收到第一个进入 @Transactional 标注方法的业务请求时,系统直接抛出异常并中断请求处理。

Spring Boot 的声明式事务依赖一个 PlatformTransactionManager Bean。绝大多数项目不需要手动定义它,因为 Boot 提供了自动装配:

  • 用 JDBC / MyBatis 时,DataSourceTransactionManagerAutoConfiguration 自动注册 DataSourceTransactionManager;
  • 用 JPA 时,JpaTransactionManagerAutoConfiguration 自动注册 JpaTransactionManager。

这些自动装配都有条件:类路径上要有对应依赖、容器里有 DataSource Bean、且没有被 exclude。一旦条件不满足或被手动排除,事务管理器就不会被注册。

StackTrace(堆栈日志)

org.springframework.beans.factory.NoSuchBeanDefinitionException:
  No bean named 'transactionManager' available:
    expected at least 1 bean which qualifies as autowire candidate.
    Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1324)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:507)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

关键特征:错误不在启动阶段,而是第一个事务方法调用时爆发,且异常栈里一定有 TransactionAspectSupport.determineTransactionManager。

Reproduce(复现代码)

启动类或配置类中显式排除了事务自动装配类,或只声明了数据源未声明事务管理器:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;

// 复现:人为排除了 DataSourceTransactionManagerAutoConfiguration
@SpringBootApplication(exclude = DataSourceTransactionManagerAutoConfiguration.class)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

业务 Service 正常使用 @Transactional:

package com.example.demo.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderService {
    @Transactional
    public void createOrder() {
        // 任何数据库操作,进入该方法即刻抛出 NoSuchBeanDefinitionException
    }
}

Root Cause(根因分析)

  1. Spring 事务切面的解析机制:当切面拦截到 @Transactional 方法时,TransactionAspectSupport.determineTransactionManager 会先尝试通过名称(默认 transactionManager)获取 PlatformTransactionManager。若注解上未指定 qualifier,Spring 会从容器中寻找唯一的事务管理器。
  2. 自动装配失效的三大诱因:
    • 线索 1:主动 exclude。在 @SpringBootApplication 或配置中误将 DataSourceTransactionManagerAutoConfiguration.class 加入了 exclude 列表。
    • 线索 2:自定义数据源未注册配套事务管理器。团队自定义了多数据源或公共 DataConfig,显式声明了 DataSource Bean,使 Spring Boot 默认的自动化数据源与事务管理器配置全面退让,但开发者未手动补上 @Bean PlatformTransactionManager。
    • 线索 3:缺少依赖。仅引入了第三方连接池但缺少 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa,导致自动装配条件 ConditionOnClass 无法达成。

可用以下命令快速排查是否存在 exclude 或检查条件评估报告:

grep -rn "exclude.*TransactionManager\|excludeName.*TransactionManager" src/main/java
java -jar app.jar --debug | grep -A2 "DataSourceTransactionManagerAutoConfiguration"

The Fix(解决方案)

方案 A(推荐):恢复自动装配,不手动管理

去掉对事务自动配置的 exclude,确保 spring-boot-starter-jdbc(或 spring-boot-starter-data-jpa)在依赖里,让 Boot 自动注册事务管理器:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

方案 B:手动补装配(多数据源 / 定制场景)

在多数据源或定制配置类中,补齐 PlatformTransactionManager Bean 定义:

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

方案 C:显式指定事务管理器名称

如果容器里有事务管理器但不叫 transactionManager(例如叫 txManager),在 @Transactional 上显式指定:

@Transactional(transactionManager = "txManager")

References(参考来源)

最后更新于 2026-09-14

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法