baomidou / dynamic-datasource

dynamic datasource for springboot 多数据源 动态数据源 主从分离 读写分离 分布式事务
https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611
Apache License 2.0
4.67k stars 1.19k forks source link

希望可以将LOOKUP_KEY_HOLDER的实现类型由NamedThreadLocal换成 TransmittableThreadLocal #550

Closed TigerToys closed 1 year ago

TigerToys commented 1 year ago

Please fill it out carefully, or it will be closed. 请认真填写,不然会直接关闭。

Enviroment

JDK Version(required): 17

SpringBoot Version(required): 3.1.1

dynamic-datasource-spring-boot-starter Version(required):4.1.1

druid Version(optional):

Describe what happened

Expected Result: com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder类 image 希望可以将LOOKUP_KEY_HOLDER的实现类型由NamedThreadLocal换成 TransmittableThreadLocal 因为在springboot中使用@Async注解时,线程池中执行代码寻找当前数据源String dsKey = DynamicDataSourceContextHolder.peek();会失效,无法切换数据源

Actual Result:

If there is an exception,or aop invalid,please attach the exception trace:

Just paste your stack trace here!

Steps to reproduce

huayanYu commented 1 year ago

用异步的少,不想支持.

  1. 你可以fork源码自己改下.
  2. 可以在异步通过参数传递.
zhnagheng commented 1 year ago

我最近也遇到异步数据源切换的问题,可以交流下吗

TigerToys commented 1 year ago

我是下载了源码然后自己改源码了,官方说不想改

 

zhnagheng commented 1 year ago

你改完使用TransmittableThreadLocal有没有上线,稳定吗

TigerToys commented 1 year ago

稳定的,我三年前就之间改源码了,这次做框架升级,然后springboot升级到3.11了,然后给mybatisplus和动态数据源顺便也升级版本了,发现这里还是不支持,就像官方提出来了,我们40多个web应用呢,目前没发现什么问题

 

oracle-fusion-middleware-team commented 10 months ago

官方其实可以改成NamedInheritableThreadLocal,支持父子线程传递;然后再实现一个TaskDecorator,用户想用线程池做异步时,加一句executor.setTaskDecorator(...)即可。见:贝斯科Part2。 这样既不用依赖 alibaba 的类库,又支持了两种最常见的异步。

zhnagheng commented 10 months ago

你的建议非常好!!!TaskDecorator的原理是在子线程每次执行run方法前后进行设置和清除ThreadLocal变量,原理和阿里的TransmittableThreadLocal 是一样的,那这样的话官方的不用动,NamedThreadLocal已经可以满足了,NamedThreadLocal可以不用改成NamedInheritableThreadLocal了吧?

张恒 @.***

 

------------------ 原始邮件 ------------------ 发件人: "baomidou/dynamic-datasource" @.>; 发送时间: 2023年11月2日(星期四) 中午1:39 @.>; @.**@.>; 主题: Re: [baomidou/dynamic-datasource] 希望可以将LOOKUP_KEY_HOLDER的实现类型由NamedThreadLocal换成 TransmittableThreadLocal (Issue #550)

官方其实可以改成NamedInheritableThreadLocal,支持父子线程传递;然后再实现一个TaskDecorator,用户想用线程池做异步时,加一句executor.setTaskDecorator(...)即可。见:贝斯科Part2。 这样既不用依赖 alibaba 的类库,又支持了两种最常见的异步。

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

nadirvishun commented 3 months ago

最主要的问题是DynamicDataSourceContextHolder中的ThreadLocal是个对象Deque<String>,导致如果用NamedInheritableThreadLocal,主线程和其下的多个子线程都共用这一个对象,如果这个对象是只读还不会有问题,但是这个对象是要操作出栈入栈的,这样共用就会导致出入栈混乱,阿里的TransmittableThreadLocal同样是浅拷贝,也有此问题。 上面三年前就改了的哥们,真的没问题吗?


TransmittableThreadLocal库中也有人问深拷贝的问题,可以参考这里的回答来自定义来重写childValue方法处理:如何实现传递对象的深拷贝 所以整体的解决方式是:

mikePengW commented 3 months ago

稳定的,我三年前就之间改源码了,这次做框架升级,然后springboot升级到3.11了,然后给mybatisplus和动态数据源顺便也升级版本了,发现这里还是不支持,就像官方提出来了,我们40多个web应用呢,目前没发现什么问题  

PR一下啊,别偷懒了~~~

oracle-fusion-middleware-team commented 2 months ago

“上下文维持”是基础软件中的一类经典问题,适合使用策略模式,做成一个单独的小库。 其实把 Spring 的 SecurityContextHolderStrategy 那一堆类拉出来改个名字就行。