【动态数据源切换失败】由于事务@Transactional注解导致动态数据源切换失效的问题

不多BB,直接上代码:

public class DataSourceKey {

    /**
     * 用户数据源
     */
    public final static String USER = "userDataSource";


    /**
     * 报表数据源
     */
    public final static String REPORT = "reportDataSource";


    /**
     * 所有数据源的集合
     */
    final static List<String> SOURCES = ImmutableList.of(USER, REPORT);


    /**
     * 根据包名找到数据源, 多数据源的前缀不能存在相同的。 例: user -> userDataSource
     *
     * @param pack 包名
     * @return 数据源名
     */
    public static String getDataSourceKey(String pack) {
        return SOURCES.stream().filter(s -> s.startsWith(pack)).findFirst().orElse(USER);
    }
}
@Component
@Aspect
@Order(-1)
@Slf4j
public class DynamicDataSourceAspect {

    @Pointcut("execution(* com.in.g.data.mapper..*.*(..))")
    public void dataSourcePointcut() {
    }

    @Before("dataSourcePointcut()")
    public void doBefore(JoinPoint point) throws Throwable {
        log.debug("切换数据源开始。。。。。。。。。。。。");
        Package pack = point.getSignature().getDeclaringType().getPackage();
        String str = StringUtils.substringAfterLast(pack.getName(), ".");
        String dataSourceKey = DataSourceKey.getDataSourceKey(str);
        DynamicDataSourceHolder.set(dataSourceKey);
        log.debug("切换数据源成功,当前数据源:{}", dataSourceKey);
    }

    @After("dataSourcePointcut()")
    public void doAfterReturning() throws Throwable {
        DynamicDataSourceHolder.clear();
    }

}
/**
 * 动态数据源持有者
 */
public class DynamicDataSourceHolder {

    public static ThreadLocal<String> keyHolder = new ThreadLocal<>();

    public static void clear() {
        keyHolder.remove();
    }

    public static void set(String key) {
        keyHolder.set(key);
    }

    public static String get() {
        return keyHolder.get();
    }

}
/**
 * 动态数据源配置
 */
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceHolder.get();
    }
}
//正确的代码   --这里偷懒了,直接controller调用dao层
@GetMapping("/testdb") public String testDateSources(){
     //缩小事务的范围 add();
rptFieldMapper.selectxxxx(); return "sss"; } @Transactional(rollbackFor = Exception.class) public void add() {
     userMapper.insertXXXX(xxxx);
 }
    //错误的代码,@Transactional注解会导致 数据源切换失败
    @GetMapping("/testdb")
    @Transactional(rollbackFor = Exception.class)
    public String testDateSources(){
  
        userMapper.insertXXXX(xxxx);

        rptFieldMapper.selectXXXX();
        

        return "sss";
    }

猜你喜欢

转载自www.cnblogs.com/gabriel-y/p/12518233.html
今日推荐