A Case for Asynchronous Non Blocking JDBC — Part One

Suchak Jani
8 min readDec 16, 2018

Background

This is a three part series

  1. Part One — This page
  2. Part Two — Click on the link
  3. Part Three — Early 2021 Update

Blocking code is the bane of modern software.

Blocking code needs more resources in terms of CPU cycles and Memory usage, which in turn increases cost to run the code.

Sections on this page

  1. We will try and understand non blocking calls
  2. We will try and understand the importance of event based systems and how they could assist in making non blocking calls

Section 1 :Blocking/Asynchronous/Asynchronous-Non-Blocking Calls

Aspects used in the diagrams for this section

  1. Java is our the language of choice
  2. We are using Java threads in our code
  3. Write Methods are Green(Asynchronous) and Red(Synchronous)
  4. Blue Methods are simple Java methods which do not block

Blocking Call

Logical Diagram

Thread Blocking call

Explanation

The below are our logical steps

  1. The Save method calls a Write method
  2. The Write method does a blocking call — say a write to disk
  3. The Thread now blocks till the write to disk is completed
  4. The Thread resumes after the blocking call returns
  5. It then calls the Notify method

Asynchronous Call

Logical Diagram

Asynchronous call

Explanation

The below are our logical steps

  1. The Save method calls a Write method which Wraps a Asynchronous call
  2. The Write Wrap method uses an Executor which spawns a new thread for writing to disk — see Appendix-1
  3. The new Thread now blocks till the write to disk is completed
  4. The Main Thread which did the save does not block and can perform other processes
  5. The new thread returns when the blocking call is completed and it calls the Notify Method

Asynchronous Non Blocking Call

Logical Diagram

Explanation

The below are our logical steps

  1. The Save method calls a Write method which uses Java NIO
  2. The Non Blocking call does not block the main Thread see Appendix-2
  3. The Non Blocking Write method now blocks till the write to disk is completed
  4. The Main Thread which did the save does not block and can perform other processes
  5. The non blocking method returns when the non-blocking call is completed and it calls the Notify Method

Conclusion

Blocking Call

  1. Blocking call should not be needed in today’s world.
  2. If we absolutely need a blocking call, we need clear justifications for the same.
  3. For example, as of today, a JDBC call to an JDBC database is a blocking call.
  4. Having said that a new JDC SQL2 package is being worked on, See Appendix-3

Asynchronous Call

  1. Making a Blocking call Asynchronous, by spawning a new Thread is a great way of not blocking the main thread
  2. It can help if the blocking call, now wrapped in a new Thread, is short lived
  3. However if the blocking call is not short lived, we could soon get into a Thread starvation issue in the JVM, See Appendix-4
  4. In the old world of monoliths, where say we have a lot of CPU and RAM resources, we could get into the issue after a certain time of running an application. Not Good to see the application hanging suddenly.
  5. In our new world, of microservices this problem may get worse depending on our deployment model.
  6. This is due to the fact that we have many small Java services. Each service has a clear responsibility and is deployed to, say a Kubernetes POD.
  7. Each POD generally has limited RAM and CPU resources per POD, See Appendix-5
  8. Hence this is not a good solution and in my view, we must avoid blocking calls as far as possible.

Non Blocking Call

  1. As seen a non blocking call does not block any threads in the system
  2. Java NIO has been out since JDK1.4 and works well
  3. There are many ways in Java to write non blocking code, See Appendix-6
  4. Asynchronous code may needs a bit of getting used to as it may not be strictly sequential.

Remote Procedure Calls vs Messaging/Events Service calls

Aspects used in the diagrams for this section

  1. A Service does one Job
  2. This is not a coding language specific section, applies to all languages

Direct Remote Procedure call

Logical Diagram RPC two Services

RPC call based services

Explanation

  1. As seen above Service One does an RPC(Remote Procedure call) to Service Two
  2. Service Two does some processing sends a response back to Service One
  3. By its very nature, this is a synchronous call
  4. Hence Service One waits for a response
  5. This could be based on low level sockets with a custom protocol or it could be HTTP/REST as a protocol, or some other protocol
  6. It is assumed, Service One and Service Two are tightly coupled and must understand each other

Logical Diagram RPC two Services timeout

Timeout

Explanation

  1. As seen, in the use case of no Response must be coded in Service One
  2. It could be due to Service Two is down, Service Two had an unexpected error or there is a network issue

Logical Diagram RPC many Services

Multiple Request Responses

Explanation

  1. What if there were other services which also needed data from our Service One
  2. When there are RPC based calls between many services, now our Service One has more work to do, as it has to deal with Synchronous requests and timeouts for each service interface it calls

Conclusion — RPC

  1. The problem here is tight coupling between the Services
  2. It lends itself to be used in a synchronous fashion as it is in essence a blocking call.
  3. Not saying it will be always a blocking call in our code. However it is easy to see why it could be easily thought of as a blocking call and thus coded in a synchronous fashion.

Queue based Events

Logical Diagram

Queue/Event based Sevices

Explanation

  1. As seen above Service “Publishes” a message on Queue X.
  2. Any services interested in that message “Subscribe” to the messages from Queue X
  3. Service Four “Publishes” a message on Queue Y, based on the message from Queue X.
  4. Service One is interested in that message and hence “Subscribes” to messages in Queue Y

Conclusion — Messaging

  1. There is no tight coupling between the Services
  2. Each service fires a message to a queue can can get on with other work it has to perform
  3. It lends itself to be used in a asynchronous fashion as it is in essence a non-blocking call.
  4. Not saying it will be always a non-blocking call in our code. However it is easy to see why it could be easily thought of as a non-blocking call and thus coded in a asynchronous fashion.
  5. There are many other advantages due to decoupling of service calls, some of them being, services can be developed independently, tested independently, when the services are running, they can now react to each others messaging and hence building a Reactive System is easier. See Appendix-7

Erlang Events

Erlang is a great highly concurrent language from Ericsson.

Please do read up on concurrency in Erlang. See Appendix-8 . The first bits of the page are a great way to know how Events are at the core of the Erlang way of doing things.

If you are a bit braver you could even try and code the whole tutorial :-)

Akka Actors and Events

Akka is very much inspired from Erlang. It runs on the JVM and supports Scala and Java.

See Appendix-9 . It is a bit longish, however worth the time invest to watch and understand a Message(event) based Actor system.

Next Steps

We will read up on JDBC and see why making it non-blocking might help.

Appendices

Appendix-1 — Java Executors

Appendix-2 — Java NIO

Appendix-3 — JDBC SQL2

Appendix-4 — Thread Starvation

Appendix-5 — Java Microservices on Kubernetes

Appendix-6 — Java Non-Blocking Algorithms

Appendix-7 — Martin Fowler Event Driven Systems

Appendix-8 — Erlang Actors

Appendix-9 — Akka Actor and Events

--

--