这篇文章主要介绍“@Transactional注解异常报错怎么解决”,在日常操作中,相信很多人在@Transactional注解异常报错怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”@Transactional注解异常报错怎么解决”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
@Transactional注解报错之多数据源
如果在加上@Transactional注解之后报错,先查看程序是否为多数据源,之前专门有一章讲解springboot的多数据源实现。多数据源的情况下加事物注解,有可能会出现问题,以下是解决方案。
1.在配置数据源的同时
一定到在其中一个配置上加上@Primary注解,其他的不要加。
package com.wys.config;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.SqlSessionTemplate;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.jdbc.datasource.DriverManagerDataSource;import javax.sql.DataSource;@Configuration@MapperScan(basePackages = "com.wys.mapper.**", sqlSessionFactoryRef = "oneSqlSessionFactory")public class OneDataSourceConfig { @Value("${spring.datasource.one.driver-class-name}") String driverClass; @Value("${spring.datasource.one.url}") String url; @Value("${spring.datasource.one.username}") String userName; @Value("${spring.datasource.one.password}") String passWord; @Primary @Bean(name = "oneDataSource") @ConfigurationProperties("spring.datasource.one") public DataSource masterDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setUrl(url); dataSource.setUsername(userName); dataSource.setPassword(passWord); return dataSource; } @Bean(name = "oneSqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource); sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:mybatis/mapper-postgre@Configuration@MapperScan(basePackages = "com.wys.mapper.**", sqlSessionFactoryRef = "oneSqlSessionFactory")public class OneDataSourceConfig { @Value("${spring.datasource.one.driver-class-name}") String driverClass; @Value("${spring.datasource.one.url}") String url; @Value("${spring.datasource.one.username}") String userName; @Value("${spring.datasource.one.password}") String passWord; @Primary @Bean(name = "oneDataSource") @ConfigurationProperties("spring.datasource.one") public DataSource masterDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setUrl(url); dataSource.setUsername(userName); dataSource.setPassword(passWord); return dataSource; } @Bean(name = "oneSqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource); sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:mybatis/mapper-postgre/*.xml")); return sessionFactoryBean.getObject(); } / // 创建事务管理器1 @Bean(name = "oneManager1") public PlatformTransactionManager txManager(@Qualifier("oneDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); }///////////////////////// @Bean(name = "oneSqlSessionFactory") public SqlSessionTemplate sqlSessionFactoryTemplate(@Qualifier("oneSqlSessionFactory")SqlSessionFactory sqlSessionFactory ) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); }}
在需要加注解的地方加上transactionManager 配置即可。
@Transactional(transactionManager ="oneManager1",rollbackFor=Exception.class)
@Transactional 错误使用的几种场景
@RestControllerpublic class AController { @Autowired AService aService; // 回滚 @GetMapping("direct") public void direct() { aService.testTransactional(); } // 不回滚 @GetMapping("indirect") public void indirect() { aService.testTransactionalIndirect(); } // 不回滚 @GetMapping("nonPublic") public void nonPublic() { aService.testTransactionalNonPublic(); } // 不回滚 @GetMapping("catchException") public void catchException() { aService.testTransactionalCatchException(); } // 不回滚 @GetMapping("sqlException") public void sqlException() throws SQLException { aService.testTransactionalSQLException(); } // 回滚 @GetMapping("sqlExceptionWithRollbackfor") public void sqlExceptionWithRollbackfor() throws SQLException { aService.testTransactionalSQLExceptionWithRollbackfor(); }}
@Servicepublic class AService { @Autowired TestTableDAO testTableDAO; // 回滚 @Transactional public void testTransactional() { ATestTable er = new ATestTable(); er.setSummary("test"); testTableDAO.save(er); throw new RuntimeException("exception"); } // 不回滚: 类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰 public void testTransactionalIndirect() { testTransactional(); } // 不回滚: @Transaction注解只对方法名为pubic的才生效 @Transactional void testTransactionalNonPublic() { ATestTable er = new ATestTable(); er.setSummary("test"); testTableDAO.save(er); throw new RuntimeException("exception"); } // 不回滚 @Transactional public void testTransactionalCatchException() { ATestTable er = new ATestTable(); er.setSummary("test"); testTableDAO.save(er); try { throw new RuntimeException("exception"); } catch (Exception e) { System.out.println("catch"); } } // 不回滚: @Transactional默认情况下只回滚RuntimeException和Error @Transactional public void testTransactionalSQLException() throws SQLException { ATestTable er = new ATestTable(); er.setSummary("test"); testTableDAO.save(er); throw new SQLException("exception"); } // 回滚: 指定在 SQLException 异常发生时回滚 @Transactional(rollbackFor = { SQLException.class }) public void testTransactionalSQLExceptionWithRollbackfor() throws SQLException { ATestTable er = new ATestTable(); er.setSummary("test"); testTableDAO.save(er); throw new SQLException("exception"); }}
@Repositorypublic interface TestTableDAO extends JpaRepository<ATestTable, Integer>, JpaSpecificationExecutor<ATestTable> { }
@Entity@Data@Table(name = "test")public class ATestTable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) int id; @Column(name = "summary", length = 512) String summary;}
到此,关于“@Transactional注解异常报错怎么解决”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!