栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

@DS注解在事务中实现数据源的切换 / @DS在事务中失效?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

@DS注解在事务中实现数据源的切换 / @DS在事务中失效?

做项目的过程中,一个实现类中可能就需要用到oracle的多个数据库。使用@DS进行数据源切换,首先要搞清楚@DS注解的正确使用方式:

当注解添加到类上,意味着此类里的方法都使用此数据源;
当注解添加到方法上时,意味着此方法上使用的数据源优先级高于其他一切配置;

起初,错误方法如下(伪代码):

@Slf4j
@Service("serviceA")
public class ServiceImpl implements Service{

    
    @Override
    @DS("database1")
    public void functionA() {
        ...
        functionB(); //调用B方法且切换为B方法的所需要的数据源
    }

    
    @Override
    @DS("database2")
    public void function B() {

    }
}

如上图所示,A方法调用B方法时,B方法的@DS注解不生效,将完全被A方法的@DS("database1)所覆盖。

———————————————————————————

在查阅了方法之后,发现加入上@Transactiona注解方式:

@Transactional 是声明式事务管理 编程中使用的注解,实质是使用了 JDBC 的事务来进行事务控制的,基于Spring 的动态代理的机制

简单来说,加入一句

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

即可让Spring事务生效。

加入后如下:

@Slf4j
@Service("serviceA")
public class ServiceImpl implements Service{

    
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    @DS("database1")
    public void functionA() {
        ...
        functionB(); //调用B方法且切换为B方法的所需要的数据源
    }

    
    @Override
    @DS("database2")
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)  
    public void function B() {

    }
}

但是,重点来了!!!!方法B仍然未生效!依然被A方法的@DS("database1)所覆盖。
———————————————

继续深入@DS注解的概念之后

错误的根源在于:上面的方法只适用于在同一个类中不同方法不同数据源的使用,不能使用事务,否则数据源不会切换。

正确的方式:创建一个新类,调用不同类中的方法

注意仍需要加上@Transactional来让事务生效,如下图(伪代码)所示:

@Slf4j
@Service("serviceA")
public class ServiceImplA implements ServiceA{
    @Resource
    ServiceImplB serviceImplB ;
    
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    @DS("database1")
    public void functionA() {
        ...
        ServiceImplB.functionB(); //调用B类的B方法
    }
}

@Slf4j
@Service("serviceB")
public class ServiceImplB implements ServiceB{
      
    @Override
    @DS("database2")
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)  
    public void function B() {

    }
}
  

最终B方法成功获取database2的数据源

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/917572.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号