Spring Boot 自动配置之 Spring transaction

什么是 Spring 事务

Spring 事务是 Spring 框架提供的一种统一事务管理机制,用来保证数据操作的一致性和完整性。它通过声明式(基于注解或 XML 配置)或编程式(手动调用 API)两种方式,简化了事务的开启、提交和回滚逻辑。底层上,Spring 事务抽象屏蔽了不同持久化技术(如 JDBC、Hibernate、JPA)的差异,让开发者能以一致的方式处理事务,从而避免数据不一致或部分提交的问题。

换句话说,Spring 事务的核心价值在于:简化事务管理、统一编程模型、确保数据安全可靠

Spring Boot 自动配置类 TransactionAutoConfiguration

包:org.springframework.boot.autoconfigure.transaction

类:TransactionAutoConfiguration

自动配置的部分核心源代码如下:

java 复制代码
@AutoConfiguration
@ConditionalOnClass(PlatformTransactionManager.class)
public class TransactionAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
	public static class TransactionTemplateConfiguration {

		@Bean
		@ConditionalOnMissingBean(TransactionOperations.class)
		public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
			return new TransactionTemplate(transactionManager);
		}

	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnBean(TransactionManager.class)
	@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
	public static class EnableTransactionManagementConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableTransactionManagement(proxyTargetClass = false)
		@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", havingValue = false)
		public static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableTransactionManagement(proxyTargetClass = true)
		@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", matchIfMissing = true)
		public static class CglibAutoProxyConfiguration {

		}

	}

}

下面我们拆开来分析

java 复制代码
@ConditionalOnClass(PlatformTransactionManager.class)

Spring Boot 自动配置的先决条件是类路径 classpath 下存在 PlatformTransactionManager 这个类;Spring Boot 下引用 "spring-boot-starter-jdbc" 这个依赖时会间接引用这个类的。

java 复制代码
    @Configuration(proxyBeanMethods = false)
	@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
	public static class TransactionTemplateConfiguration {

		@Bean
		@ConditionalOnMissingBean(TransactionOperations.class)
		public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
			return new TransactionTemplate(transactionManager);
		}

	}

使用 Spring 事务,必须要给到 PlatformTransactionManager ,这里要求 Spring 容器中必须存在唯一候选的实现 PlatformTransactionManager 接口的类的 Bean,自定义 Bean 的代码可以参考如下:

java 复制代码
@Configuration
public class DataSourceConfig {

    @Bean
    @ConditionalOnMissingBean
    public DataSource dataSource() {
        return new DriverManagerDataSource("jdbc:mysql://localhost:3306/your_database", "username", "password");
    }

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

}

如果 Spring 容器中不存在 TransactionOperations 接口实现类的 Bean 的话,会自动创建一个 单例的 Bean(TransactionTemplate 类实现了 TransactionOperations 接口),此 Bean 的名称为 "transactionTemplate"

那 TransactionTemplate 都使用在哪些场景呢?

  • TransactionTemplate 是 Spring 提供的编程式事务管理工具,用于在代码中显式控制事务的开启、提交和回滚。

  • 它通过回调机制(execute 方法)将事务逻辑与业务逻辑分离,避免手动编写繁琐的 try-catch-finally 事务控制代码。

  • 使用时可以灵活设置事务传播行为、隔离级别和超时时间,满足不同业务场景的需求。

  • 适合在 无法使用声明式事务(@Transactional) 的场景下,或需要对事务边界进行更细粒度控制时使用。

  • 常见应用场景包括:批量操作中部分步骤需要独立事务、跨方法调用时避免事务传播问题、或在框架/工具类中封装事务逻辑。

java 复制代码
	@Configuration(proxyBeanMethods = false)
	@ConditionalOnBean(TransactionManager.class)
	@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
	public static class EnableTransactionManagementConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableTransactionManagement(proxyTargetClass = false)
		@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", havingValue = false)
		public static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableTransactionManagement(proxyTargetClass = true)
		@ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", matchIfMissing = true)
		public static class CglibAutoProxyConfiguration {

		}

	}

上面这个配置类的作用,是为 Spring 的声明式事务管理(即使用 @Transactional注解) 启用合适的 AOP 代理机制:

  • @EnableTransactionManagement 本身就是开启基于 AOP 的事务管理的关键注解。

  • proxyTargetClass 参数决定了 Spring 在为 @Transactional 方法生成代理时,使用 JDK 动态代理 (接口代理)还是 CGLIB 子类代理

    • proxyTargetClass = false → 使用 JDK 动态代理(要求目标类有接口)。

    • proxyTargetClass = true → 使用 CGLIB 代理(通过生成子类实现代理,适合没有接口的类)。

  • 这段配置通过 @ConditionalOnBooleanProperty(name = "spring.aop.proxy-target-class", ...) 来根据配置文件中的 spring.aop.proxy-target-class 属性,自动选择 JDK 或 CGLIB 代理。

  • 因此,它确实是针对 @Transactional注解生效时所依赖的代理机制 的配置。

使用 TransactionTemplate 显式控制事务

java 复制代码
    @Autowired
    private TransactionOperations transactionTemplate;

    @Override
    public List<String> listDepartmentsByCorpId(String corpId) {
        return transactionTemplate.execute(status -> List.of("dingtalk_dept1", "dingtalk_dept2"));
    }

使用Spring 的声明式事务管理(即使用 @Transactional注解)

java 复制代码
    @Transactional(rollbackFor = Exception.class)
    public List<String> listDepartmentsByCorpId(String corpId) {
        return List.of("dingtalk_dept1", "dingtalk_dept2");
    }

总结

Spring Boot 通过 TransactionAutoConfiguration 自动装配事务管理器和 TransactionTemplate,让开发者在引入数据源依赖后即可开箱即用事务功能,无需手动配置。它同时启用基于 @Transactional 的声明式事务管理,并根据 spring.aop.proxy-target-class 自动选择 JDK 动态代理或 CGLIB 代理

相关推荐
小bo波8 小时前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
用户3521802454759 小时前
🎆从 Prompt 到 Skill:让 Spring AI Agent 学会"装新技能"
人工智能·spring boot·ai编程
nanxun8861 天前
记一次诡异的 Docker 容器"串包"故障排查
java
用户1563068103511 天前
Day01 | Java 基础(Java SE)
java
行者全栈架构师2 天前
Maven dependency:tree 的 8 个高级用法
java·后端
行者全栈架构师2 天前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_02 天前
mac(m5)平台编译openjdk
java
唐青枫3 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马3 天前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户3721574261353 天前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java