Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Akka: how to make non-blocking JDBC requests

Tags:

java

akka

jdbc

I am brand new to Akka (Java lib) and am trying to understand if Akka can be used to make non-blocking requests to JDBC, and if so, what that it would look like. I believe most JDBC drivers open a socket connection and block the thread that created it until a particular JDBC response is received, and so there might not be much Akka can do to help here, but I am wondering if there is a way (perhaps through Futures or Agents?) that Akka could help improve performance, and allow the actor system to continue processing data, while an existing JDBC call is being made and awaiting a response.

I found this article which is a bit vague/cryptic, but it sounds like futures might be the key here. However that article doesn’t really show any meaningful (real-world) code examples, and so I’m still at a loss. So let’s say we have a stored procedure, sp_make_expensive_calculation, that normally takes 10 - 30 seconds to return a response and that is normally called via JDBC like so:

String makeExpensiveCalculationSql = "{call sp_make_expensive_calculation(?)}";
callableStatement = dbConnection.prepareCall(makeExpensiveCalculationSql);
callableStatement.setInt(1, 10);

// Could take up to 30 seconds to complete.
callableStatement.executeUpdate();

int answer = callableStatement.getString(2);

Can Akka do anything to help here so that the actor system can continue processing data (and even make other sp_make_expensive_calculation calls) while we wait for the first call to return?

like image 308
smeeb Avatar asked Jul 27 '15 01:07

smeeb


People also ask

Is Akka non-blocking?

Asynchronous, non-blockingThe true non-blocking power comes from actions that do not block either you (the calling thread) or someone else (some secondary thread). Best exemplified with an Akka actor. An actor, unlike what you may have read from the webs, is not something active.

What is dispatcher in Akka?

Dispatchers are responsible for scheduling all code that run inside the ActorSystem . Dispatchers are one of the most important parts of Akka.NET, as they control the throughput and time share for each of the actors, giving each one a fair share of resources. By default, all actors share a single Global Dispatcher.

What is actor model in Akka?

Akka Actors The Actor Model provides a higher level of abstraction for writing concurrent and distributed systems. It alleviates the developer from having to deal with explicit locking and thread management, making it easier to write correct concurrent and parallel systems.


1 Answers

The general pattern is to use separate execution contexts: one for synchronous database access via JDBC, one for reactive processing. Also see the Akka futures documentation.

When you create an actor system it creates its own execution context -- this is the one you use for your normal reactive processing with actors. You need to create a second execution context for the JDBC calls. You will then pass this execution context to the future factory as shown here in the Akka documentation.

In order to be notified when the future has completed, you can (optionally) use the pipe construct (also shown in the previous link, but in the preceeding documentation section). The effect of the pipe construct is to take the return value of the future, whose type is that of the future's generic type parameter (for example, the result of your query), and post it to the specified actor's mailbox.

The code executed by the future must not modify or even read any mutable data owned by the initiating actor (or any actor, for that matter). You'll need to tag the result of the future so that when it arrives in the actor's mailbox the actor will be able to associate it with the initial JDBC request. Finally, your actor will eventually receive the result and you can continue to process it (subject to Akka's at-most-once delivery guarantees).

Note that you don't have to use two execution contexts -- one will also work, but there would be a danger of your database requests consuming all available threads in the execution context.

like image 64
kilo Avatar answered Sep 24 '22 07:09

kilo