Spring Boot 自动配置之 Spring transaction
什么是 Spring 事务
Spring 事务是 Spring 框架提供的一种统一事务管理机制,用来保证数据操作的一致性和完整性。它通过声明式(基于注解或 XML 配置)或编程式(手动调用 API)两种方式,简化了事务的开启、提交和回滚逻辑。底层上,Spring 事务抽象屏蔽了不同持久化技术(如 JDBC、Hibernate、JPA)的差异,让开发者能以一致的方式处理事务,从而避免数据不一致或部分提交的问题。
换句话说,Spring 事务的核心价值在于:简化事务管理、统一编程模型、确保数据安全可靠。
Spring Boot 自动配置类 TransactionAutoConfiguration
包:org.springframework.boot.autoconfigure.transaction
类:TransactionAutoConfiguration
自动配置的部分核心源代码如下:
@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 {}}}
下面我们拆开来分析
@ConditionalOnClass(PlatformTransactionManager.class)
Spring Boot 自动配置的先决条件是类路径 classpath 下存在 PlatformTransactionManager 这个类;Spring Boot 下引用 “spring-boot-starter-jdbc” 这个依赖时会间接引用这个类的。
@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 的代码可以参考如下:
@Configuration
public class DataSourceConfig {@Bean@ConditionalOnMissingBeanpublic DataSource dataSource() {return new DriverManagerDataSource("jdbc:mysql://localhost:3306/your_database", "username", "password");}@Bean@ConditionalOnMissingBeanpublic PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}}
如果 Spring 容器中不存在 TransactionOperations 接口实现类的 Bean 的话,会自动创建一个 单例的 Bean(TransactionTemplate 类实现了 TransactionOperations 接口),此 Bean 的名称为 “transactionTemplate”。
那 TransactionTemplate 都使用在哪些场景呢?
-
TransactionTemplate 是 Spring 提供的编程式事务管理工具,用于在代码中显式控制事务的开启、提交和回滚。
-
它通过回调机制(
execute
方法)将事务逻辑与业务逻辑分离,避免手动编写繁琐的try-catch-finally
事务控制代码。 -
使用时可以灵活设置事务传播行为、隔离级别和超时时间,满足不同业务场景的需求。
-
适合在 无法使用声明式事务(@Transactional) 的场景下,或需要对事务边界进行更细粒度控制时使用。
-
常见应用场景包括:批量操作中部分步骤需要独立事务、跨方法调用时避免事务传播问题、或在框架/工具类中封装事务逻辑。
@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 显式控制事务
@Autowiredprivate TransactionOperations transactionTemplate;@Overridepublic List<String> listDepartmentsByCorpId(String corpId) {return transactionTemplate.execute(status -> List.of("dingtalk_dept1", "dingtalk_dept2"));}
使用Spring 的声明式事务管理(即使用 @Transactional
注解)
@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 代理