Dashboard > ADBCJ > Home
Home
Added by Jim Yang, last edited by Mike Heath on Oct 01, 2007  (view change)
Labels: 


Asynchronous Database Connectivity in Java

Asynchronous Database Connectivity in Java (ADBCJ) is an API for interacting with relational databases similar to the Java Database Connectivity (JDBC) API. The big difference with ADBCJ is that all database operations are done asynchronously. Connecting to the database, executing SQL, committing or rolling back a transaction, and closing a database connection are all done asynchronously.

Warning

ADBCJ is still very experimental and the code is currently alpha quality.

You may download and build ADBCJ using Subversion from http://swamp.homelinux.net/svn/thesis/adbcj/. We plan to eventually move the ADBCJ code repository over to Safehaus.org.

ADBCJ API

The ADBCJ API is similar to JDBC and the Java Concurrency API. In many ways it resembles the JSR 203 asynchronous I/O API.

To interact with the database, application developers primarily work with the DbSession interface. The DbSession interface defines methods for executing queries, executing update statements, starting and stopping transactions, and closing the session which are all done asynchronously. Instead of blocking and waiting for the server to respond, DbSession returns a DbFuture object. A DbFuture object represents the pending database operation. A DbFuture object may be used to cancel the pending operation, block until the operation completes, or the DbFuture object can be used to register a callback that will be invoked when the database operation completes.

ADBCJ requires a different way of thinking than traditional sequential database access. However, some of the benefits of ADBCJ far exceed the cost of having to solve problems differently. For example, ADBCJ makes it possible to execute multiple database queries concurrently. If you're using multiple databases or even multiple database connections to the same database, executing queries in parallel can improve performance significantly. ADBCJ also is much better suited for asynchronous event-driven servers (servers that use NIO) than JDBC drivers.

ADBCJ currently provides three database drivers. The first database driver is a JDBC wrapper that uses an ExecutorService to execute JDBC queries asynchronously. The other two database drivers use Apache MINA to communicate with MySQL and Postgresql, respectively. MINA uses Java NIO which makes it possible to open and use a large number of database connections with only a few threads which is much more efficient than the JDBC wrapper.

Connecting to a database

To connect to a database, you must first acquire a ConnectionManager. To obtain a connection manager, a database driver needs to be registered with ADBCJ. Each ADBCJ driver has a class named Adbcj in it. To register the driver you need to either invoked Adbcj.init() directly, or call Class.forName() and pass in the absolute name of the Adbcj class. The Class.forName() method is how most JDBC driver register themselves with the JDBC DriverManager. The following example shows how to obtain a ConnectionManager for a MySQL database.

To register the MySQL driver you can do:

Obtaining a ConnectionManager
// The following methods for registering the ADBCJ driver are functionally equivalent

// Register the driver statically
org.safehaus.adbcj.mysql.Adbcj.init();

// Or register the driver dynamically
Class.forName("org.safehaus.adbcj.mysql.Adbcj");

ConnectionManager connectionManager = ConnectionManagerProvider.createConnectionManager("adbcj:mysql://localhost/test", "username", "password");

The first parameter is the connection URL. Notice how the connection URL is very similar to a JDBC connection URL. The second parameter is the database user's name used to connect to the database. The third parameter is the database user's password.

Once you have a ConnectionManager, you may obtain a database connection using ConnectionManager.connect(). connect() returns a DbFuture<Connection> object. Using the DbFuture<Connection> object, you may invoke the get() to block until the database connection has completed or you may use a callback that will be invoked when the database connection has been established. See the following example:

Connecting to the database
// Tell the connection manager you want a connection
DbFuture<Connection> connectionFuture = connectionManager.connect();
// Block until the connection is available
Connection connection = connectionFuture.get();
// ...

// Or you could simply do
Connection connection = connectionManager.connect().get();
// ...

// Or use the callback
ConnectionManager.connect().addListener(new DbListener<Connection>() {
    public void onCompletion(DbFuture<Connection> future) throws Exception {
        // This will not block because the future is guaranteed to have finished in the callback
        Connection connection = future.get();
        // ...
    }
}
References (ADBCJ)
Site running on a free Atlassian Confluence Open Source Project License granted to Safehaus. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.4 Build:#809 Jun 12, 2007) - Bug/feature request - Contact Administrators