Spring中@Transactional注解使用哪个PlatformTransactionManager实现?
Spring选择PlatformTransactionManager的核心规则
1. 单事务管理器场景
如果项目的Spring上下文中仅存在一个PlatformTransactionManager实现类的Bean,Spring会直接将其作为默认事务管理器,所有未额外指定的@Transactional注解都会使用该管理器。
比如仅引入JDBC相关依赖时,Spring Boot会自动注册DataSourceTransactionManager,所有加了@Transactional的方法默认都会用它管理JDBC事务。
2. 多事务管理器共存场景
当项目中存在多个PlatformTransactionManager实现类的Bean时,Spring会按如下优先级选择:
- 优先匹配
@Transactional注解中显式指定的事务管理器,比如@Transactional("redisTransactionManager")就会直接使用名称为redisTransactionManager的Bean。 - 若注解未指定,则优先使用标注了
@Primary的事务管理器Bean。 - 既没有指定也没有
@Primary的Bean时,Spring会抛出NoUniqueBeanDefinitionException异常,提示存在多个可用事务管理器无法确定使用哪一个。
3. 多资源操作场景的特殊说明
你示例中单个事务方法同时操作SQL数据库、Redis、JMS的场景,常规的单事务管理器无法覆盖多个不同类型资源的事务管控,此时分为两种情况:
- 若你未引入分布式事务方案:
@Transactional只会生效你选中的单事务管理器对应的资源事务,其他资源的操作不受事务控制。比如你默认使用JDBC事务管理器,那么只有SQL操作会在异常时回滚,Redis写入、JMS消息发送只要执行成功就不会回滚,会出现数据不一致。 - 若你引入了JTA分布式事务实现(比如Atomikos、Narayana):Spring会使用JTA事务管理器,通过XA协议协调多个资源的事务,实现跨SQL、Redis、JMS的事务一致性。
你给出的示例代码:
@Transactional public void transactionMethod(){ saveToSqlDatabase(); saveToRedis(); publishToTopic(); }
在没有额外配置分布式事务的情况下,默认仅对SQL操作生效事务。
内容的提问来源于stack exchange,提问作者Balconsky
相关产品推荐
相关产品推荐

