Skip to content

grahamedgecombe/db

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Database API

A thin layer on top of the JDBC API that takes care of awkward boilerplate code, such as retrying transactions that are aborted because of a deadlock and reconnecting to the database server if the connection is lost.

Features

  • Enforces the use of transactions.
  • Automatically re-connects the database if the connection is lost (e.g. due to a timeout.)
  • Automatically retries transactions if they fail due to deadlock. Deadlocks are a normal occurrence in many database servers and it is the user's responsibility to retry transactions that are aborted because of a deadlock. The maximum number of attempts and delay between attempts is configurable.
  • Maintains a configurable, fixed-size pool of open connections.
  • Provides both a synchronous and an asynchronous API.

Installation

This project is available in the Maven Central Repository. Add the following dependency to your pom.xml file to use it:

<dependency>
  <groupId>com.grahamedgecombe.db</groupId>
  <artifactId>db</artifactId>
  <version>1.0.2</version>
</dependency>

The artifacts are signed with my personal GPG key.

Usage

Synchronous API

DataSource dataSource = ...;
DatabaseService service = DatabaseService.builder(dataSource).build().start();

try {
    String result = service.execute(connection -> {
        try (PreparedStmt stmt = connection.prepareStatement("SELECT 'hello, world';")) {
            try (ResultSet rs = stmt.executeQuery()) {
                rs.next();
                return rs.getString(1);
            }
        }
    });

    System.out.println(result); // prints "hello, world"
} catch (ExecutionException ex) {
    ex.printStackTrace();
}

service.stop();

Asynchronous API

DataSource dataSource = ...;
DatabaseService service = DatabaseService.builder(dataSource).build().start();

ListenableFuture<String> future = service.executeAsync(connection -> {
    try (PreparedStmt stmt = connection.prepareStatement("SELECT 'hello, world';")) {
        try (ResultSet rs = stmt.executeQuery()) {
            rs.next();
            return rs.getString(1);
        }
    }
});

Futures.addCallback(future, new FutureCallback<String>() {
    @Override
    public void onSuccess(String result) {
        System.out.println(result); // prints "hello, world"
    }

    @Override
    public void onFailure(Throwable ex) {
        ex.printStackTrace();
    }
});

service.stop(); // any transactions submitted before stop() are executed before stop() returns

Documentation

Javadocs are available on javadoc.io.

Dependencies

License

This project is available under the terms of the ISC license, which is similar to the 2-clause BSD license. See the LICENSE file for the copyright information and licensing terms.

About

A thin layer on top of the JDBC API that takes care of awkward boilerplate code.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages