DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Building a CRUD Application With Spring and SimpleJdbcMapper
  • How to Marry MDC With Spring Integration
  • How Spring and Hibernate Simplify Web and Database Management
  • Functional Endpoints: Alternative to Controllers in WebFlux

Trending

  • How an AI Software Factory Works: From Developer Intent to Production
  • Avoiding AI Debt as a Team
  • AI Agents Need an Identity Plane: Rethinking Enterprise Authorization for Autonomous Software
  • Stop Writing Database Migration Scripts: Declarative Schema Sync for Java

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Frameworks
  4. Spring 5 WebFlux and JDBC: To Block or Not to Block

Spring 5 WebFlux and JDBC: To Block or Not to Block

With Spring 5's awaited promise of more reactive support, let's examine both how we can make JDBC more asynchronous and the problems that brings.

By 
Grygoriy Gonchar
·
Updated Jun. 02, 17 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
97.9K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

The 5th version of the Spring Framework brings a huge step forward in Functional and Reactive Programming support. You don’t need ApplicationContext or dozens of annotations to have the simplest REST API up and running. Spring 5 will offer lightweight Web Functions and reactive Web Flux support that can help this transition happen. Those new features make Java and Spring 5 good candidates for building reactive web applications

To be reactive, according to The Reactive Manifesto, you have to be Responsive, Resilient, Elastic, and Message Driven. The last criteria in this list caused big movement into the asynchronous way of communications. This includes asynchronous RPC and messaging libraries, database drivers, and more. RDBMSs are quite powerful and useful. The official instruments for database access on JVM provided by database vendors are drivers implementing JDBC API. But JDBC is designed to be blocking and consumes threads per database call. You will not find in the API itself methods or interfaces allowing you to get query results in another thread. There is also an opinion that a transactional database is not a fit for the reactive concept:

The concept of a transaction doesn’t naturally fit the reactive world, as it’s about blocking a resource, which is exactly what you want to avoid here

I would partially agree. However, it depends on how exactly you will be using your relational database. Moreover, in the new era of highly scalable SQL databases (such as Amazon’s Aurora or Google’s Cloud Spanner) reactivity is a fit to achieve high throughput by using them together. The question is what shall we do when we are building applications on top of a SQL database with reactivity in mind. One option would be to use alternative SQL clients that are fully non-blocking. Some examples include here and here.

Of course, none of these drivers is officially supported by database vendors yet. Also, functionality is way much less attractive when compared to mature JDBC-based abstractions such as Hibernate or jOOQ.

An alternative idea came to me from the Scala world. We can dispatch blocking calls into an isolated Thread Pool to avoid mixing blocking and non-blocking calls together. This will allow us to control the overall number of threads and will let the CPU serve non-blocking tasks in the main execution context, applying various optimisations.

Assuming that we have a JDBC-based implementation, such as Spring Data JPA, which is indeed blocking.

import org.springframework.data.repository.CrudRepository;

public interface AddressRepository extends CrudRepository<Address, Long> {}


We can make its execution asynchronous and dispatch it to a dedicated thread pool.

@Service
public class AddressService {

    private final AddressRepository repository;

    private final Scheduler scheduler;

    public AddressRouter(AddressRepository repository, @Qualifier("jdbcScheduler") Scheduler scheduler) {
        this.repository = repository;
        this.scheduler = scheduler;
    }

    public Mono<Iterable<Address>> findAll() {
        return async(() -> repository.findAll());
    }

    private <T> Mono<T> async(Callable<T> callable) {
        return Mono.fromCallable(callable).publishOn(scheduler);
    }
}


Our Scheduler for JDBC should be configured by using a dedicated Thread Pool with a size count equal to the number of connections.

@Configuration
public class SchedulerConfiguration {
    private final Integer connectionPoolSize;

    public SchedulerConfiguration(@Value("${spring.datasource.maximum-pool-size}") Integer connectionPoolSize) {
        this.connectionPoolSize = connectionPoolSize;
    }

    @Bean
    public Scheduler jdbcScheduler() {
        return Schedulers.fromExecutor(Executors.newFixedThreadPool(connectionPoolSize));
    }

}


However, there are difficulties with this approach. The main one is transaction management. In JDBC, transactions are possible only within a single java.sql.Connection. To make several operations in one transaction, they have to share a connection. If we want to make some calculations in between them, we have to keep the connection. This is not very effective, as we keep a limited number of connections idle while doing calculations in between.

This idea of an asynchronous JDBC wrapper is not new and is already implemented in the Scala library Slick 3. Finally, non-blocking JDBC may come along on the Java roadmap. As it was announced at JavaOne in September 2016, and it is possible that we will see it in Java 10.

Spring Framework

Published at DZone with permission of Grygoriy Gonchar. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Building a CRUD Application With Spring and SimpleJdbcMapper
  • How to Marry MDC With Spring Integration
  • How Spring and Hibernate Simplify Web and Database Management
  • Functional Endpoints: Alternative to Controllers in WebFlux

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook