事务导致的切换数据源失败

项目场景:

提示:这里简述项目相关背景:
一块儿业务中,会出现业务中切换数据库的情况,在应用事务时可能会导致的切换数据源失败


问题描述

提示:这里描述项目中遇到的问题:

@Transactional( rollbackFor = Exception.class)
    public void deleteTask(String taskNo) {
        Task task = this.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskNo, taskNo));
        this.update(Wrappers.<Task>lambdaUpdate().set(Task::getDelFlag, 0).eq(Task::getTaskNo, taskNo));        lawcasePortraitHandleService.run(Arrays.asList(LawcasePortraitHandleConst.TypeEnum.sandtableData), task.getLawcaseId());
    }

会出现找不到表的报错:
在这里插入图片描述

原因分析:

发现数据表存在,但是数据库的选择有问题,排查发现mapper里用的数据源是对的,并尝试手动切换数据源,仍旧无法解决问题。发现用了事务的注解@Transactional,可能是事务导致数据源切换失败


解决方案:

提示:这里填写该问题的具体解决方案:将注解@Transactional( rollbackFor = Exception.class)更换为@DSTransactional即可。

### 动态数据源切换失败的原因分析与解决方案 #### 开启 Debug 日志以便于诊断问题 为了更好地理解动态数据源的工作流程并定位潜在的问题,建议首先开启 `debug` 级别的日志记录。这有助于观察到每次请求时所使用的具体数据源名称以及任何异常情况的发生。 ```yaml logging: level: com.baomidou.dynamic.datasource: DEBUG ``` 通过上述配置可以查看更详细的日志信息来帮助排查问题[^2]。 #### 断点调试拦截器 如果仍然无法找到根本原因,则可以在 `DynamicDataSourceAnnotationInterceptor` 和 `DynamicRoutingDataSource` 中设置断点来进行深入调试。这种方式能够直观地看到程序执行路径及其参数变化,从而更容易发现逻辑上的偏差或错误配置。 #### 检查事务管理的影响 当应用程序中存在未正确处理的分布式事务时,可能会干扰到数据源之间的正常切换操作。确保所有的跨库查询都在同一个全局事务下完成,并且合理运用传播行为属性(Propagation Behavior),例如 `REQUIRES_NEW` 或者 `NOT_SUPPORTED` 来隔离不同业务单元间的事务影响范围。 #### 验证 AOP 是否生效 确认 Aspect-Oriented Programming (AOP) 已经被正确启用并且作用到了预期的方法上。对于那些由同一类内的其他方法间接调用的目标函数来说,默认情况下它们是不会受到切面增强功能约束的;因此需要特别注意此类情形下的实现细节。 #### 排除 Shiro AOP 干扰因素 某些安全框架如 Apache Shiro 使用了自己的代理机制,在特定条件下可能导致标准 Spring AOP 行为失常进而引发数据源切换失败的现象。此时应该尝试调整两者之间协作方式或者寻找替代方案以规避冲突风险。 #### 审核组件初始化次序 由于项目启动过程中各 Bean 实例化时机的不同,有时会出现依赖关系颠倒的情况——即某个负责加载外部资源的对象尚未准备好就被提前访问了。针对这种情况可以通过显式指定 `@DependsOn` 注解强制规定先后顺序,亦或是利用事件监听模式延迟部分敏感环节的操作直至整个上下文环境稳定下来为止。 #### 更新 Druid 连接池版本 较低版次的 Druid 可能不具备完善的多数据源支持特性,故而推荐升级至最新稳定发行版以获得更好的兼容性和性能表现。同时也要留意官方文档里关于迁移指南的相关说明以防引入不必要的改动成本。 #### 异步任务中的特殊考量 考虑到异步编程模型特有的并发特性和生命周期管理模式,务必保证所有涉及数据库交互的任务都运行在一个有效的线程环境中,并且遵循既定的数据源分配策略。必要时可借助工具类辅助完成此过程,比如采用自定义 TaskExecutor 负责调度工作流的同时传递必要的上下文信息给子线程使用。 #### 关闭默认数据源自动注入 为了避免与其他第三方扩展包发生命名空间碰撞而导致意外覆盖现象的发生,应当禁用掉内置的数据源自动化装配选项: ```java @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class Application { } ``` 这样做之后再手动声明所需的多个数据源实例即可有效防止混淆不清的局面出现[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值