我的编程空间,编程开发者的网络收藏夹
学习永远不晚

@Transactional注解异常报错之多数据源详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

@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 错误使用的几种场景

 
@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;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

@Transactional注解异常报错之多数据源详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

这篇文章主要介绍“@Transactional注解异常报错怎么解决”,在日常操作中,相信很多人在@Transactional注解异常报错怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”@Transact
2023-06-29

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录