java 两个service一个有事务一个没有_被标记为事务的方法互相调用的坑(上)

本文探讨了在Spring中使用@Transactional注解时遇到的问题,当一个有事务的方法调用另一个无事务的方法,导致预期的事务行为未生效。分析了事务传播行为和AOP代理原理,揭示了直接内部调用不会触发事务拦截的原因。
摘要由CSDN通过智能技术生成

相信大家一定用过Spring中的注解型事务,配合上Spring Boot,只需要在方法上打一个@Transactional 就可以完成,真香。

但是如果大家对其中的机制一知半解的话,可能一不小心就会掉进坑,然后久久无法爬出来。

下面我就分享下 被标记为事务的方法互相调用的坑

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

首先我写两个事务方法:

@Autowired
 AccountMapper mapper;
 @Transactional
 @Override
 public void insertCodeBear() {
 Account account = new Account();
 account.setAccount("CodeBear");
 account.setPassword("CodeBear");
 mapper.insert(account);
 }
 @Transactional
 @Override
 public void insertCodeMonkey() {
 Account account = new Account();
 account.setAccount("CodeMonkey");
 account.setPassword("CodeMonkey");
 mapper.insert(account);
 }

现在我想在insertCodeBear方法里面调用insertCodeMonkey方法,但是insertCodeMonkey不是很重要,就算失败,也不能影响到insertCodeBear方法的执行,但是insertCodeMonkey该回滚的还是要回滚,我们很容易写出如下代码:

@Autowired
 AccountMapper mapper;
 @Transactional
 @Override
 public void insertCodeBear() {
 try {
 insertCodeMonkey();
 } catch (Exception ex) {
 }
 Account account = new Account();
 account.setAcco
在Spring Boot应用,如果需要在一个方法同时操作多个数据源,并希望对这些操作进行事务管理,通常会采用`JPA`(Java Persistence API)或者`DataSourceTransactionManager`结合`@Transactional`注解的方式。下面是一个基本步骤: 1. **配置多个数据源**:通过`spring-boot-admin-starter-data-jpa` 或者自定义`DataSource` bean来配置多个数据源,比如`@Primary`标记一个默认的数据源。 ```java @Configuration @EnableTransactionManagement(proxyTargetClass = true) public class DataSourceConfig { @Autowired private PlatformTransactionManager transactionManager; @Bean(name = "dataSourceA") public DataSource dataSourceA() { // 数据源A的配置 } @Bean(name = "dataSourceB") public DataSource dataSourceB() { // 数据源B的配置 } @Profile("multiDataSource") @Bean(qualifier = "transactionManager") @Primary public PlatformTransactionManager multiDataSourceTransactionManager() { return new DelegatingTransactionManager() { @Override protected PlatformTransactionManager delegateTransactionManager() { if (ThreadLocalTransactionManager.class.isAssignableFrom(transactionManager.getClass())) { return new TransactionTemplate(dataSourceA()); } else { return transactionManager; } } }; } } ``` 2. **使用@Transactional注解**:在需要跨数据源事务方法上添加`@Transactional`注解,指定事务隔离级别、传播行为等。这里可以利用`@Qualifier`注解来指定事务管理器。 ```java @Service @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW, qualifier = "transactionManager") public class MultiDataSourceService { @Autowired @Qualifier("dataSourceB") private JdbcTemplate jdbcTemplateB; @Autowired private JdbcTemplate jdbcTemplateA; public void methodThatUsesBothDataSources() { jdbcTemplateA.update(...); jdbcTemplateB.update(...); // 这里两个操作会被放在一个事务 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值