• dynamic-datasource + parallelStream数据源切换失效


    记录一次使用动态数据源+java8的ParallelStream并行流导致的数据源切换失效问题,先看一下异常记录:

    代码如下:

    1. @Service
    2. @DS(DataSourceConst.ORDER)
    3. public class OrderService {
    4. @Resource
    5. private VendorService vendorService;
    6. public void getVendor() {
    7. vendorService.getVendorInfo(Arrays.asList(1L));
    8. }
    9. }
    1. @Service
    2. @DS(DataSourceConst.VENDOR)
    3. public class VendorService {
    4. @Resource
    5. private VendorInfoRepository vendorInfoRepository;
    6. public List getVendorInfo(List vendorIdList) {
    7. List> partition = Lists.partition(vendorIdList, 500);
    8. return partition.parallelStream().flatMap(idList -> {
    9. LambdaQueryWrapper wrapper = new LambdaQueryWrapper()
    10. .in(VendorInfo::getId, idList);
    11. return vendorInfoRepository.select(wrapper).stream();
    12. }).collect(toList());
    13. }
    14. }

    分析问题:因为dynamic-datasource是通过AOP的方式,在调用方法前切换数据源的,而java8的ParallelStream需要新开线程,这些新的线程是独立于原来的线程的,原来线程中的数据源切换并不能传递到新的线程中,这就可能导致在新的线程中对数据库的操作还是使用的原来线程的数据源,不能正确地进行数据源切换。

    解决问题:把@DS放在方法上,代码如下:

    1. @Service
    2. @DS(DataSourceConst.VENDOR)
    3. public class VendorService {
    4. @Resource
    5. private VendorInfoRepository vendorInfoRepository;
    6. @DS(DataSourceConst.VENDOR)
    7. public List getVendorInfo(List vendorIdList) {
    8. List> partition = Lists.partition(vendorIdList, 500);
    9. return partition.parallelStream().flatMap(idList -> {
    10. LambdaQueryWrapper wrapper = new LambdaQueryWrapper()
    11. .in(VendorInfo::getId, idList);
    12. return vendorInfoRepository.select(wrapper).stream();
    13. }).collect(toList());
    14. }
    15. }

    以上是问题的一次简单记录,并为深挖如有不对的地方请评论指导。

  • 相关阅读:
    C语言——用递归函数计算n!
    明厨亮灶视频监控分析系统
    微信快捷回复软件
    【规范】看看人家Git提交描述,那叫一个规矩
    C++ 内存泄漏检测与实现
    ​HTTP/2 和 Websocket​
    【LeetCode】【剑指offer】【栈的压入、弹出序列】
    实时云渲染技术在虚拟仿真领域的应用
    关于VS2019启动调试项目时提示拒绝访问
    JS sort排序
  • 原文地址:https://blog.csdn.net/itxiaobaishu/article/details/133341303