【動態數據源切換失敗】由於事務@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";
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM