解析配置文件自动装配 DataSource + AbstractRoutingDataSource + AOP 实现动态数据源 - 补充:兼顾事务回滚以及分布式事务的情况

前两篇文章已经介绍了动态数据源的具体实现过程,在经过一段时间的使用后,发现了两个比较严重的问题,在这里进行补充说明。

事务执行失败时没有切回默认数据源

@Transactional 注解的方法意味着使用数据库事务执行方法中的 sql 操作,默认情况下当方法抛出不受检查异常时,事务会进行回滚,我所实现的动态数据源方案通过 AOP 和注解的方式切换数据源, @Transactional 方法执行前切换目标数据源,执行完成后切换回默认数据源。

但当方法抛出不受检查异常时,AOP 方法无法执行到切回默认数据源的语句,因此在下次使用数据源时就会出错,期望使用的是默认数据源,然而并不是。

解决方法是把切回默认数据源的语句放在 finally(try {} funally {}) 块中执行。

    @Around(value = "@annotation(dataSource)")
    public Object changeDataSource(ProceedingJoinPoint point, DataSource dataSource) throws Throwable {

        DsKey dsKey = dataSource.dsKey();
        if (!DynamicDataSource.contains(dsKey)) {
            return null;
        }

        DynamicDataSource.setDataSourceKey(dsKey);
        try {
            return point.proceed();
        } finally { // 兼顾事务回滚的情况
            DynamicDataSource.clearDataSourceType(); // 恢复默认
        }
    }

@Transactional 注解的方法中使用多个数据源

此时事务只会对前一个数据源生效,这里就涉及到分布式事务的知识,详细的分析之后再进行总结,

可先参考以下文章:

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值