Limitations of the synchronous model

During the investigation of persistence options with Spring Framework or even Java in general, we have looked through JDBC, JPA, Hibernate, EclipseLink, Spring Data JDBC, and Spring Data JDBC, and all these API and libraries are inherently synchronous and blocking. Even though they are almost always used for data retrieval from external services involving network calls, they do not permit non-blocking interactions. Consequently, all previously mentioned  APIs and libraries conflict with the reactive paradigm. A Java thread that issues a query to the database is doomed to be blocked until the first piece of data arrives or a timeout occurs, and this is pretty wasteful from the perspective of resource management in a reactive application. As described in Chapter 6WebFlux Async Non-Blocking Communication, this approach massively limits the throughput of the application and requires many more server resources and, therefore, more money.

It is wasteful to make IO requests in a blocking manner no matter whether this is an HTTP request or a database request. Also, JDBC-based communication usually uses a whole pool of connections to execute queries in parallel. In contrast, the widely used HTTP2 protocol allows using the same TCP connection to send and receive multiple resources at the same time. This approach decreases the number of occupied TCP sockets and allows greater concurrency both for client and server (in our case, this is the database). Consider the following diagram:

Diagram 7.15 Comparison between usual database communication and a communication protocol that allows multiplexing, such as HTTP2

Of course, connection pools exist to save time when opening new connections. It is also possible to implement a communication layer beneath JDBC in order to leverage multiplexing like in HTTP2, but still, the code preceding the JDBC level has to be synchronous and blocking.

Likewise, when processing large query results that occupy few batches, communication with the database cursor (a control structure that enables iteration over the query result records) looks like the left side of the preceding diagram. Chapter 3, Reactive Streams - the New Streams' Standard, analyzes the difference between the communication options in detail from the perspective of Reactive Streams, but the same arguments apply to network interactions.

Even if a database provides an asynchronous non-blocking driver capable of communicating efficiently and leveraging connection multiplexing, we are not able to get the full potential of it when using JDBC, JPA, or Spring Data JPA. Consequently, to build an entirely reactive application, we have to abandon synchronous techniques and make an API using reactive types.

To summarize this section, conventional and well-established JDBC and JPA implementations may become a bottleneck in a modern reactive application. JDBC and JPA are most likely to use too many threads and too much memory at runtime, at the same time requiring aggressive caching to limit lengthy synchronous requests and blocking IO.

It is not the synchronous model that is bad; it just does not fit well within a reactive application and most likely becomes a limiting factor. However, these models may successfully coexist. Both synchronous and reactive approaches have their pros and cons. For example, so far, the reactive persistence approach cannot propose any ORM solutions that are even close to JPA in terms of features.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.239.44