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
相关产品推荐
相关产品推荐

