Search code examples
javaspring-datareactive-programmingnonblockingproject-reactor

Difference between blocking Spring Data and reactive Spring Data?


Why do we need non-blocking db connectors if we can just wrap the standard blocking query result in a reactive stream? Are Mongo, Redis, etc non-blocking connectors actually streaming data from the datasource, or fetch data in a blocking fashion, then stream from in-memory? An example of querying Mongo:

public interface ItemReactiveRepository extends ReactiveMongoRepository<Item,String> {

    //
}

...
Flux<Item> itemsFlux = itemReactiveRepository.findAll();

and

public interface ItemRepository extends MongoRepository<User, String> {
    // 
}
...
List<Item> itemsList = itemRepository.findAll(); 
Flux<Items> itemsFlux = Flux.fromIterable(itemsList );

If someone can take a time to explain, or throw in a link I'd be grateful


Solution

  • Short answer is scalability.

    In the blocking world (JDBC, JPA, etc.) if you want to execute many database queries concurrently, then you'll need as many threads as many concurrent database queries you want to execute. This works fine until a certain point. However, threads are not free: they require memory, and context switching costs CPU time. So the more concurrency you have, the more your system struggles.

    Here comes non-blocking IO (R2DBC, Reactive Mongo Driver, etc.) and reactive which lets you get rid of this thread-per-connection model and lets you achieve the same concurrency by using a fixed, low number of threads (usually equals to number of CPU cores). This model provides much higher scalability.

    If you just wrapped your blocking code into a reactive stream, you wouldn't get rid of the thread-per-connection model, you'd just hide the problem and would end up with the same scalability issues.