温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

@Transactional注解异常报错怎么解决

发布时间:2022-01-25 15:10:34 来源:亿速云 阅读:367 作者:iii 栏目:开发技术

这篇文章主要介绍“@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;
    /**
     * @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);
        }
    }

    2.一定要在需要使用事物注解的数据源配置里

    加上创建事务管理器

    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)

    @Transactional 错误使用的几种场景

     @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注解异常报错怎么解决”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI