溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

@Transactional注解異常報錯怎么解決

發布時間:2022-01-25 15:10:34 來源:億速云 閱讀:389 作者: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

    亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女