使用多数据源的注意事项

项目场景:

关于多数据源在代码中不同位置的使用和配置。

问题描述

1、如果我在mapper中没有加入@Repository或@Mapper,那么@DS(“fault”)就不会生效。

在这里插入图片描述主要是因为:
在Java的Spring框架中,@Repository是一个用于标注数据访问层(DAO层)的组件注解。这个注解有以下主要用途:
组件扫描:当Spring进行bean的自动扫描时,带有@Repository注解的类会被注册为Spring管理的bean。
异常转换:在DAO层,如果抛出的是checked exception(例如,SQLException),Spring会将其转换为运行时异常,通常是DataAccessException或其子类,这使得上层调用者无需处理checked exception。
在这里插入图片描述在这个例子中,UserRepository被标记为一个DAO组件,Spring将管理它的生命周期,并且可以自动处理任何可能抛出的数据库相关异常。
如果我在mapper中没有加入@Repository,那么多数据源是无法生效的。
这是因为:
在MyBatis Plus中,@DS 注解用于动态数据源切换,它通常应用在Service层或DAO层的方法上,以指示该方法应该使用哪个数据源。然而,@Repository 或 @Mapper 注解主要是Spring用来识别并管理Bean的。
如果你在Mapper接口上没有使用 @Repository 或 @Mapper 注解,Spring可能不会将其识别为一个Bean,这意味着这个Mapper将不会被正确地装配到Spring容器中。因此,即使你在这个未被Spring管理的Mapper上使用了 @DS 注解,Spring也无法识别并应用这个注解,因为该Mapper本身就没有被Spring管理。
为了确保 @DS 注解能够正常工作,你需要确保以下几点:
Mapper接口已经被Spring识别并管理。这通常意味着你需要在Mapper接口上使用 @Mapper 或 @Repository 注解。
数据源切换的逻辑(例如,DynamicDataSource 配置)已经被正确地实现并在Spring中配置。
如果你的项目使用了MyBatis Plus,确保相关的配置已经完成,包括数据源的配置以及数据源切换的拦截器配置。

2、使用Stream是可以直接查询

使用Stream API进行查询与数据源的选择机制是不同的。当你在Mapper接口的方法中使用Stream API时,实际上你是在操作已经从数据源获取的数据集合。Stream API是Java 8引入的一个功能,用于对集合进行操作,如过滤、映射、排序等,但它本身并不涉及数据源的选择或连接。
当你在Mapper中执行如下的SQL查询:

List<String> enterprises = sqlSession.selectList("getVehicleEnterprisesList");

这里假设 sqlSession 是由MyBatis提供的,用于执行SQL语句并返回结果集。selectList 方法会根据Mapper接口中的方法签名和配置找到对应的SQL语句,并执行查询。此时,数据源的选择应该已经在MyBatis的配置或Spring的配置中确定好了,而不是在执行查询时动态决定的。
一旦数据被加载到内存中,你可以使用Stream API对这些数据进行操作,例如:

List<String> filteredEnterprises = enterprises.stream()
    .filter(enterprise -> enterprise.startsWith("A"))
    .collect(Collectors.toList());

这里的Stream操作完全发生在内存中,与数据源无关。因此,即使没有使用 @DS 注解,Stream API也能正常工作,因为它不涉及数据源的选择或切换。
总结来说,@DS 注解用于在执行数据访问操作时动态选择数据源,而Stream API则用于在数据已经加载到内存后对数据进行操作。两者的作用范围和机制是不同的。

3、@Transactional(rollbackFor = Exception.class) 事务会影响到@DS(“fault”)的使用。

在Spring框架中,@Transactional@DS 注解的使用确实存在一定的交互关系,尤其是在多数据源的场景下。@Transactional 注解用于声明式事务管理,而 @DS 注解用于动态数据源切换。它们之间的冲突主要来源于Spring AOP的代理机制和事务管理器的选择。
当一个方法同时使用了 @Transactional@DS 注解时,Spring会按照以下方式处理:
事务管理器的选择:@Transactional 注解默认会使用配置中的默认事务管理器。如果你的应用中有多个数据源,每个数据源通常会有自己的事务管理器。如果方法上没有显式指定使用哪个事务管理器,那么Spring会使用默认的那个,这通常对应于默认的数据源。
数据源切换:@DS 注解用于在运行时动态改变数据源。然而,当事务开始时,Spring会锁定当前的数据源连接,直到事务结束。这意味着在事务的上下文中,数据源的切换可能会被事务管理器的行为所限制。
为了解决这种冲突,你可以采取以下几种策略:
显式指定事务管理器:在 @Transactional 注解中通过 transactionManager 属性明确指定要使用的事务管理器,确保它与 @DS 注解指定的数据源相匹配。

@DS("fault")
@Transactional(transactionManager = "faultTransactionManager", rollbackFor = Exception.class)
public void someMethod() {
    // your code here
}

使用不同的事务传播行为:根据你的业务需求,可以调整 @Transactional 的 propagation 属性。例如,如果一个方法内部需要调用另一个已经包含事务的方法,你可以设置 propagation = Propagation.REQUIRES_NEW 来确保内部调用时使用一个新的事务,从而不影响外部事务的数据源选择。
避免在事务中进行数据源切换:尽量将需要不同数据源的操作放在不同的事务中,这样可以避免事务和数据源切换之间的冲突。
总之,
@Transactional 和 @DS
注解的冲突主要在于事务管理器的选择和数据源的切换。通过显式指定事务管理器和调整事务传播行为,你可以有效地解决这一问题,确保在多数据源环境下事务的一致性和隔离性。

  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值