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 代理

相关推荐
计算机毕设指导63 分钟前
基于微信小程序的智能停车场管理系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea
码云数智-大飞5 分钟前
零拷贝 IPC:用内存映射文件打造 .NET 高性能进程间通信队列
java·开发语言·网络
懈尘7 分钟前
深入理解Java的HashMap扩容机制
java·开发语言·数据结构
indexsunny8 分钟前
互联网大厂Java面试实战:从Spring Boot到Kafka的技术与业务场景解析
java·spring boot·redis·面试·kafka·技术栈·microservices
roman_日积跬步-终至千里10 分钟前
【Java并发】Tomcat 与 Spring:后端项目中的线程与资源管理
java·spring·tomcat
独自破碎E11 分钟前
IDEA 提示“未配置SpringBoot配置注解处理器“的解决方案
java·spring boot·intellij-idea
yqd66611 分钟前
RabbitMQ用法和面试题
java·开发语言·面试
2601_9498095914 分钟前
flutter_for_openharmony家庭相册app实战+照片详情实现
android·java·flutter
4311媒体网17 分钟前
Libvio.link 页面布局与数据分布
java·php
奋斗的小方20 分钟前
01 一文读懂UML类图:核心概念与关系详解
java·uml