You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成Oracle R2DBC提示publisher不支持多订阅者如何解决

问题结论

该报错是Oracle R2DBC早期版本的已知使用限制,与配置是否遗漏无关。

异常触发原因

Oracle R2DBC 1.0.0版本之前,驱动返回的Connection对应的Publisher是单订阅者设计,仅允许被订阅一次。当你使用Mono.zip同时触发两个Spring Data R2DBC仓库查询时,Spring框架底层会尝试多次订阅连接Publisher,就会抛出This publisher does not support multiple subscribers异常。

可行解决方案
  • 方案1:升级依赖版本(最推荐)
    直接将Oracle相关依赖升级到修复该问题的版本即可:

    implementation('com.oracle.database.r2dbc:oracle-r2dbc:1.1.0')
    implementation('com.oracle.database.jdbc:ojdbc11:21.13.0.0')
    

    1.0.0及以上版本的Oracle R2DBC已经官方支持多订阅者,无需修改业务代码即可解决问题。

  • 方案2:业务代码加缓存操作符
    若暂时无法升级依赖,可给每个数据库查询对应的Mono/Flux添加.cache()操作符,缓存发布者结果避免重复订阅连接,修改后的代码如下:

    message.flatMap { fromMessage ->
        Mono
            .zip(
                listOf(
                    dimensionAdviserRepository
                        .findFirstByEntityIdOrderByFromDateDescToDateDesc(message.adviserKey)
                        .map { it?.adviserKey ?: -1L }
                        .switchIfEmpty(Mono.just(-1L))
                        .cache(),
                    dimensionAccountRepository
                        .findFirstByEntityIdOrderByFromDateDescToDateDesc(fromMessage.accountKey!!)
                        .map { it?.account_key ?: -1L }
                        .switchIfEmpty(Mono.just(-1L))
                        .cache()
            ))}
    
  • 方案3:显式开启R2DBC连接池
    低版本Spring Boot默认未开启R2DBC连接池,连接池返回的连接发布者天然支持多订阅。首先引入连接池依赖:

    implementation('io.r2dbc:r2dbc-pool')
    

    再在配置文件中添加连接池配置:

    spring.r2dbc.pool.enabled=true
    spring.r2dbc.pool.max-size=20
    spring.r2dbc.pool.initial-size=5
    

内容的提问来源于stack exchange,提问作者Xuân Dũng Đoàn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 20:06:00