Reactor Mono实现会话查询兜底:A不存在则校验B会话
实现思路
Reactor 里完全可以实现「判断Mono为空时走后续逻辑」的需求,不需要自己额外写判断逻辑,直接用原生的switchIfEmpty操作符即可。
原有代码的问题
之前的实现逻辑错位:入口处只判断了sessionA的字符串是否非空,就直接返回了findByKeyOne生成的Mono。但Mono是懒执行的,这一步根本不会真的去数据库查数据,自然也不知道后续这个Mono最终是会返回有效会话,还是空结果。只要提前把这个Mono返回,后面写的sessionB判断分支就永远不会被触发,哪怕A查出来是空的也没用。
具体修正方法
所有的分支判断都要放在流的执行链路里,根据每个Mono实际执行后的返回结果做切换,不要在方法入口直接命令式返回Mono。完整代码如下:
String sessionA = "1"; String sessionB = "2"; public Mono<Session> getSession() { // 先构造会话A的查询流:如果sessionA是空串,直接生成空Mono Mono<Session> sessionAFlow = StringUtils.isEmpty(sessionA) ? Mono.empty() : myDatabaseService.findByKeyOne(sessionA); return sessionAFlow // 当A的查询流走完没有拿到结果(空Mono)时,自动切去查会话B .switchIfEmpty( // 构造会话B的查询流:如果sessionB是空串,直接生成空Mono StringUtils.isEmpty(sessionB) ? Mono.empty() : myDatabaseService.findByAnotherSession(sessionB) ) // 当B的查询也拿不到结果时,抛出预期异常 .switchIfEmpty(Mono.error(new RuntimeException("所有会话均无效"))); }
逻辑适配说明
这个实现完全匹配你提的业务目标,而且完全兼容你现有的数据库服务代码:
- 只要sessionA非空,且
findByKeyOne能查到有效会话:直接返回A的结果,不会触发B的查询 - 不管是sessionA没传值,还是A在数据库查无结果、甚至查询异常被你包装成空Mono返回,都会自动进入B的查询分支
- 当sessionB也没传值、或者B也查无结果时,最终抛出对应的业务异常
- 不需要修改你现有的
findByKeyOne等数据库层的实现,因为不管是无结果还是异常,只要返回空Mono,就会被switchIfEmpty捕获触发后续逻辑。
内容的提问来源于stack exchange,提问作者Katie
相关产品推荐
相关产品推荐

