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

如何缓存Mono对象?响应式仓库改造后的缓存存储实现疑问

How to Update Cache Logic with Reactive Mono in Spring

Hey there! Since you're new to reactive programming, let's walk through how to fix this cache update step by step—this is a super common gotcha when moving from imperative to reactive code!

The Core Problem

In your old imperative code, repository.save(entity) returned the actual saved entity immediately, so you could pass it straight to putIntoCache. But now repository.save(entity) returns a Mono<T>—this is a lazy, asynchronous stream that will emit the saved entity only when subscribed to. If you tried to pass savedEntity (the Mono itself) into putIntoCache, you'd end up caching the Mono object instead of the actual entity, which isn't what you want.

Solution 1: Use flatMap for Asynchronous Cache Operations

First, you should update your entityCacheService.putIntoCache method to return a Mono<Void> instead of void. This keeps the entire pipeline reactive (no blocking operations!). Then use flatMap to chain the save and cache operations:

// First, ensure putIntoCache returns Mono<Void>
Mono<T> savedEntity = repository.save(entity)
    .flatMap(saved -> 
        // Wait for the cache operation to complete, then emit the saved entity
        entityCacheService.putIntoCache(saved.getId(), saved)
            .thenReturn(saved)
    );
  • flatMap waits for the repository.save(entity) Mono to emit the saved entity.
  • It then runs the cache update (which returns a Mono<Void>).
  • thenReturn(saved) ensures the original saved entity is passed down the pipeline, so any downstream subscribers still get the entity they need.

Solution 2: Use doOnSuccess for Synchronous Cache Operations (Not Ideal, But Works)

If you can't modify entityCacheService right now and putIntoCache is a synchronous method, use doOnSuccess—this is a "side effect" operator that runs code when the Mono emits a successful value, without altering the data stream:

Mono<T> savedEntity = repository.save(entity)
    .doOnSuccess(saved -> 
        // Runs when the save completes successfully
        entityCacheService.putIntoCache(saved.getId(), saved)
    );

⚠️ Important Note: Synchronous operations in a reactive pipeline can block threads, which defeats the purpose of reactive programming. Try to refactor putIntoCache to be asynchronous (return Mono<Void>) as soon as possible—you can wrap synchronous cache calls using Mono.fromRunnable() or subscribeOn() to offload them to a separate thread pool.

Key Rules to Remember

  • Never use block() here! Blocking will freeze the reactive thread and break non-blocking behavior.
  • Always chain operations using reactive operators (flatMap, doOnSuccess, etc.) instead of trying to extract values directly from Mono/Flux.
  • Cache writes in reactive code need to be part of the reactive pipeline, not separate imperative calls.

内容的提问来源于stack exchange,提问作者Saurabh Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:25:33