Spring Data Reactive Cassandra deleteById无作用问题求助
环境版本
- Java: 20.0.0
- Springboot: 3.0.1
- Cassandra: 4.0
Repository 定义
public interface UserRepository extends ReactiveCassandraRepository<User, UUID> { }
问题代码(方法调用)
@Service public class UserService { @Autowired UserRepository userRepository; public Mono<Void> removeIfExistingUser(UserRequest userRequest) { String userId = userRequest.getUserId(); String assetType = userRequest.getAssetType(); String assetId = userRequest.getAssetId(); Flux<User> userFlux = userRepository.findByUserIdAndAssetTypeAndAssetId(userId, assetType, assetId); List<User> userList = userFlux.collectList().block(); if (!userList.isEmpty()) { User user = userList.get(0); Mono<Void> userMono = userRepository.deleteById(user.getId()); userMono.subscribe(); } return null; } }
问题排查与修复
核心问题原因
- 阻塞式操作破坏响应式流程:使用
block()强制阻塞线程获取结果,违背响应式非阻塞设计,同时会中断响应式上下文传递,导致后续删除操作无法正确绑定到请求或事务上下文。 - 异步操作未被正确等待:手动调用
subscribe()触发删除后,立即返回null,上层调用者无法感知并等待删除操作完成,导致异步删除操作可能在上下文结束前被终止,Cassandra未执行实际删除。
修复后的代码
@Service public class UserService { private final UserRepository userRepository; // 构造注入替代@Autowired,提升代码可测试性 public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public Mono<Void> removeIfExistingUser(UserRequest userRequest) { String userId = userRequest.getUserId(); String assetType = userRequest.getAssetType(); String assetId = userRequest.getAssetId(); // 全程保持响应式链式调用,无阻塞操作 return userRepository.findByUserIdAndAssetTypeAndAssetId(userId, assetType, assetId) .next() // 仅获取匹配的第一个用户 .flatMap(user -> userRepository.deleteById(user.getId())) // 链式执行删除 .then(); // 转换为Mono<Void>,标识操作完成 } }
修复说明
- 移除
block()和subscribe(),通过响应式算子next()、flatMap()、then()串联整个流程,确保操作在响应式上下文内执行。 - 方法返回完整的
Mono<Void>,让上层调用者(如Controller)可以订阅并等待删除操作完成,避免异步操作被中断。 - 使用构造注入替代字段注入,符合Spring最佳实践,提升代码可维护性。
内容的提问来源于stack exchange,提问作者Prafulla Kumar Sahu
相关产品推荐
相关产品推荐

