這篇文章主要介紹“@Transactional注解異常報錯怎么解決”,在日常操作中,相信很多人在@Transactional注解異常報錯怎么解決問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”@Transactional注解異常報錯怎么解決”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
如果在加上@Transactional注解之后報錯,先查看程序是否為多數據源,之前專門有一章講解springboot的多數據源實現。多數據源的情況下加事物注解,有可能會出現問題,以下是解決方案。
一定到在其中一個配置上加上@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; /** * @program: * @description: 數據庫配置1 * @author: wys * @create: 2019-12-03 16:20 **/ @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(); } @Bean(name = "oneSqlSessionFactory") public SqlSessionTemplate sqlSessionFactoryTemplate(@Qualifier("oneSqlSessionFactory")SqlSessionFactory sqlSessionFactory ) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
加上創建事務管理器
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; /** * @program: * @description: 數據庫配置1 * @author: wys * @create: 2019-12-03 16:20 **/ @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)
@RestController public 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(); } }
@Service public 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"); } }
@Repository public 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注解異常報錯怎么解決”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。