RT ,前几天无意间发现 Spring MVC + JDBC 经典组合中的事务与 Kotlin 协程似乎存在一定的兼容问题
依据 Spring 官方文档 的说明是,Spring 目前仅支持 R2DBC 事务与 Kotlin 协程的组合,JDBC 事务需要用到 ThreadLocal ,在协程中启动事务会出问题,相关讨论和问题可以参考以下链接:
我目前对响应式框架的了解还不足,所以我想请教一下,是不是为了充分发挥 Kotlin 协程的优势,就必须将项目整体迁移到 WebFlux + R2DBC 下?
另外,我也想了解一下,即将到来的 JDK 21 的虚拟线程和 Kotlin 协程会有怎样的关系?
感谢各位的帮助与意见。
1
iPisces77 2023-09-11 23:11:37 +08:00 1
kt 协程也只有 webflux 支持的好,servlet 本身就没有原生支持 kotlin 的协程,所以 webmvc 不太适用,一般也就自己执行多任务会用到 kt 协程
|
2
Leviathann 2023-09-11 23:14:10 +08:00 1
kotlin conf 2023 有 kotlin team leader Roman 关于这个话题的 talk
|
3
iPisces77 2023-09-11 23:22:36 +08:00
补充:所有用到 ThreadLocal 的基本对协程都是不支持
|
4
dlimeng 2023-09-11 23:27:20 +08:00
[Feature][SolidUI-Web] Design the page, hide the static legends and the legends data tab
https://github.com/CloudOrc/SolidUI/issues/141 |
5
netabare 2023-09-12 04:02:07 +08:00 via Android 2
不了解 Webflux ,不过用过 Quarkus ,印象中协程可以和响应式编程类库提供的 Future (我这里是 Uni/Multi )互转,但在类似 Event bus 、ORM 等地方的兼容性欠佳。可能在 Spring 也是类似的状态?
不清楚 op 想要引入 coroutine 是什么作用,如果只是用来写简单 API 可能可行? Quarkus 里面是可以的。如果是配合 ORM 或者 handler 来写的话,框架提供的响应式写法是原生支持最好的,考虑到现在 Java 的发展状况,我也不认为 Spring 会提供原生的对 coroutine 的支持。如果 op 坚持想要用 coroutine 的话可能需要对 handler 做分层设计。 另外这些都是响应式和完全异步的技术栈,如果是基于 servlet 的话还是洗洗睡吧。ThreadLocal 应该也很难。 |
6
yazinnnn 2023-09-12 09:05:33 +08:00
写 reactive 会变得不幸
慎重 |
7
HollowDreamStar 2023-09-12 09:37:06 +08:00
直接冲 j21, 大道至简
|
8
githmb 2023-09-12 10:34:00 +08:00
JDBC 只有事务有问题吗,它不是古老的 BIO 吗?就算用协程也得 spawn 一个单独的线程吧
|
9
mmdsun 2023-09-13 16:10:24 +08:00 1
kotlin 协程调度器是不是可以传个 Executors 池的参数?
到时候应该可以用 Executors.newVirtualThreadPerTaskExecutor()给协程调度器。类似这种关系吧 Java 虚拟线程支持 ThreadLocal: https://openjdk.org/jeps/444#Thread-local-variables ,kotlin 协程应该需要单独处理。 Reactive transaction 只支持 webflux ,要用得话只能换。但迁移很麻烦 kotlin 协不太清楚是怎么实现的,一般来说协程是一种基于状态机( state machine )的编译器技术,可以把将异步代码分解为多个挂起点( suspension point ),并在每个挂起点保存和恢复协程的状态。 |
10
Akitora OP @mmdsun #9
确实可以通过自定义 Dispatcher 来达到手动指派线程池的效果 https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html 虚拟线程支持 ThreadLocal 的话,到时候现有的基于 JDBC 的 ORM 能直接兼容就好了,支持 R2DBC 的 ORM 略少… |