Last week at JavaOne, Oracle Database JDBC Architect Douglas Surber gave a talk about what is next for JDBC. There was an advance look at a possible new Java standard for accessing SQL databases: a non-blocking API. This would be a separate API that gives access to the same databases as JDBC, rather than a replacement or extension of JDBC.

Douglas Surber spoke to Voxxed and provided some further insights into what this new standard might look like, and what it aims to achieve.

The JDBC Project

JDBC (Java Database Connectivity) is a Java standard that provides the interface for connecting programs written in Java to data in relational databases. The requests are encoded in SQL and passed to the program that manages the database. It is defined and implemented through the java.sql interfaces.

Traditionally, to get around the pain of synchronous database calls, more threads would be created. However this can lead to more thread scheduling, contention and a slow system. High throughput apps can require careful calibration to avoid thread blocks and high latency.

Non-blocking API

The non-blocking API standard aims to never have any user thread blocks. It is an alternate API for database access – not an extension or replacement for the current JDBC API.

According to Surber: “The JavaOne session focused on the API as a standard, not on any particular implementation. As much as possible the API does not specify an implementation. In some ways it is more implementation agnostic than the java.sql API. Oracle does have a proof of concept implementation for the Oracle Database. It is derived from the Type 4 Oracle Database JDBC driver, but heavily revised to be non-blocking all the way down. It is built on Java NIO Selectors and so is basically non-blocking. But this is just a proof of concept. As a Java standard, vendors could implement it however they thought best.”

Why not just create another thread?

According to Surber, threads are too expensive to be a scalable solution. The aim is to minimise the number of threads used for database access:

“Java community experience is that threads are expensive. Even idle threads consume resources. Scheduling threads and context switches between threads consumes scarce CPU cycles. For much of the history of Java creating another thread was the answer when something blocked but we as a community have learned that just doesn’t scale to the degree we need. We have discovered that it is far better to keep the number of threads small, same magnitude as the number of hardware threads the machine supports, and keep all the threads busy all the time. Idle threads and blocked threads waste resources.”

What about existing JDBC APIs?

There are already multiple non-blocking JDBC APIs. We asked what the non-blocking JDBC API standard will provide that other solutions (e.g. Streams, NodeJS) do not: 

“NodeJS is not a Java API. Non-blocking database access in NodeJS depends on the entire infrastructure of NodeJS and that infrastructure does not exist in Java SE. On the other hand the Streams API is clearly part of Java SE and is an obvious candidate for building a non-blocking JDBC API.”

Streams are inherently blocking

“When we started this project three years ago our first cut at an API was based on Streams. We quickly realized that Java Streams are inherently blocking at a basic level. The Java Core Library Team was very clear about this. They were also very clear that this was fundamental to the current Streams model and was unlikely to change in the time frame we were interested in if ever. While we could create a Streams based non-blocking JDBC API it wouldn’t be useful. The value of building on Streams is the ability to leverage the Streams infrastructure. Since that is basically blocking, any non-blocking JDBC API based on Streams would start to block as soon as it connected with the rest of the Streams infrastructure. This didn’t satisfy our requirements.”

API needs to integrate with the Java class library

“We made an effort to search out and study every non-blocking database access API even vaguely related to Java. While I can’t say we looked at them all, we certainly tried. None of them met all our requirements. The biggest stumbling block is that to be a Java standard an API has to integrate well with the rest of the Java class library. Many of the alternatives depend on infrastructure that isn’t part of the Java class library. Monadic programming is well represented in the class library by java.util.concurrent.CompletionStage and CompletableFuture. So the API presented at JavaOne builds on those.”

Execution Model

For the new standard, everything will be an operation. Operations consist of SQL, parameter assignments, result handling, submission and CompletableFuture. The user thread creates the Operation and submits it. The implementation of the non-blocking API will execute the Operation asynchronously.

Operations can be grouped. Members are submitted to a group, and OperationGroup is submitted to a unit. It will have its own result handling and CompletableFuture. The members will be executed in the order they are submitted, or parallel in any order. The error response can be dependent, skipping remaining group members, or independent, leaving the other group members unaffected.

We asked Surber what the use case is for an asynchronous call to a database, and how the Operation object comes into play:

“Database access does not have to be synchronous so much as it needs to be ordered; each database access follows the preceding one in a well-defined order. Ordered database accesses does not have to be synchronous. The non-blocking JDBC API presented in the JavaOne session makes that very overt. Each database access is represented by an Operation object. Operations are executed in a well-defined order so, for example, a query will definitely precede an update if that’s what the programmer specifies. At the same time nothing blocks. Creating an Operation does not require any blocking. Creating a sequence of Operations, including ones that depend on prior ones, does not require any blocking. So the programmer can clearly specify a sequence of database accesses without blocking and without entering call-back hell, which is another critical goal of the project.”

Code examples

Code examples here are reproduced from Douglas Surber’s JavaOne slides. They are an example for what the standard could look like, but everything is subject to change.

Trivial Insert

public void trivialInsert(DataSource ds) { 
   String sql = "insert into tab values (<<i id>>, <<i name>>, <<i answer>>)"; 
   try (Connection conn = ds.getConnection()) { 
      conn.countOperation(sql) 
         .set("id", 1, JdbcType.NUMERIC) 
         .set("name", "Deep Thought", JdbcType.VARCHAR) 
         .set("answer", 42, JdbcType.NUMERIC) 
         .submit(); 
   }
}

The parameters are still preliminary. In this example they correspond to:

<<i in_parameter>>
<<o out_parameter>>
<<io inout_parameter>>
<<column_name>> same as column_name <<o column_name>>

For example:

select <<id>>, concat(first_name, ‘ ‘, family_name) <<o name>>
from tab where id = <<i target>> /* <<not_a_marker>> */

According to Surber: “Any occurrence of the parameter marker pattern that is not a parameter marker must be escaped, e.g. in literals or in comments”.

Trivial Select

public void trivialSelect(DataSource ds, List<Integer> result) {
 String sql = "select <<id>>, <<name>>, <<answer>> " +
              "from tab where answer = <<i target>>";
 try (Connection conn = ds.getConnection()) {
    conn.<List<Integer>>rowOperation(sql) 
      .set("target", 42, JdbcType.NUMERIC) 
      .rowAggregator( (ignore, row) -> {
          result.add(row.get("id", Integer.class));
          return null;
       } )
       .submit();
 }
}

Further examples (Basic Select, Big Insert, Parallel Update and more) are on the slides.

Next steps

In terms of when we can hope to see the new standard, we may be waiting a while:

“The goal of the non-blocking JDBC project from the beginning was for the API to be a Java standard. There are several non-standard non-blocking JDBC APIs already so there is no significant benefit from creating yet another. The benefit only comes with a standard API. None of those non-standard APIs have achieved much penetration, not because they are technically deficient, but purely because they are non-standard.”

“The Java community is moving toward non-blocking APIs in many areas so there is a clear need for a standard non-blocking JDBC API. Oracle would like to have some kind of standard non-blocking JDBC in Java as soon as possible for our own needs. It certainly doesn’t have to be the API presented in the JavaOne session, though that’s what we will take to the Expert Group as a jumping off point. Exactly when a non-blocking JDBC API will appear in Java is a function of how fast the JDBC Expert Group and the JCP can reach consensus. Our target is Java 10, but that’s pretty aggressive.”

For now, the JDBC Expert Group will continue development, and it will be submitted through the Java Community Process.

Waiting on a query: Non-blocking Database Access

| Mind the Geek| 8,502 views | 1 Comment
About The Author
- Katharine is a Java developer by trade, turned Community & Content Manager for Voxxed. Helping developers learn and share knowledge. Contact me at kbe@voxxed.com with any news, articles or tutorials.

1 Comment

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>