Skip to content

viragtripathi/cockroachdb-jdbc-wrapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

22 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Build GitHub release License

CockroachDB JDBC Wrapper

A lightweight, zero-maintenance Java library that wraps your existing PostgreSQL JDBC connection to automatically retry transient failures commonly encountered when using CockroachDB. These include:


🎯 Purpose

CockroachDB provides strong consistency and serializable isolation, which can lead to expected 40001 transaction retry errors. Instead of pushing that complexity to every application developer or service maintainer, this library provides a simple, non-intrusive solution that:

  • Automatically retries transactional errors internally
  • Works transparently with your existing JDBC logic
  • Adds no proxies, reflection, bytecode hacks, or driver replacements
  • Includes integration-tested retry logic with CockroachDB
  • Lets you opt-in to optional wrapper types if needed

🧰 Features

  • RetryableExecutor – simple utility to retry logic with execute() and executeVoid()
  • Optional RetryableDataSource and RetryableConnection for automatic retry of commit() and rollback()
  • Built-in handling of well-known CockroachDB/SQL state codes
  • Supports Resilience4j backoff and retry configuration
  • Zero-maintenance: no proxy servers, agents, or instrumentation

πŸš€ Quick Start

1. Add Dependency

<dependency>
  <groupId>com.cockroachdb</groupId>
  <artifactId>cockroachdb-jdbc-wrapper</artifactId>
  <version>0.1.0</version>
</dependency>

If using the slim JAR, include dependencies manually:

<dependency>
  <groupId>io.github.resilience4j</groupId>
  <artifactId>resilience4j-core</artifactId>
</dependency>
<dependency>
  <groupId>io.github.resilience4j</groupId>
  <artifactId>resilience4j-retry</artifactId>
</dependency>
<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
</dependency>

πŸ’‘ Download Options

File Description
cockroachdb-jdbc-wrapper-0.1.0.jar Slim JAR (no deps, requires Resilience4j + JDBC)
cockroachdb-jdbc-wrapper-0.1.0-all.jar Uber JAR with Resilience4j shaded

βœ… Usage Examples

βœ… Recommended (Minimal) – Use RetryableExecutor

RetryableExecutor executor = new RetryableExecutor();

executor.executeVoid(() -> {
    try (Connection conn = dataSource.getConnection()) {
        conn.setAutoCommit(false);
        // ... your DB ops
        conn.commit();
    }
});

This keeps your code unchanged while centralizing retry logic.


🧩 Optional: Wrap Your DataSource or Connection

If you want automatic retries for commit() / rollback() without calling the executor explicitly:

PGSimpleDataSource pgds = new PGSimpleDataSource();
pgds.setUrl("jdbc:postgresql://localhost:26257/defaultdb?sslmode=disable");
pgds.setUser("root");

DataSource retryable = new RetryableDataSource(pgds);
Connection conn = retryable.getConnection();  // wraps with retry logic for commit/rollback

βœ… These wrappers are safe, pure Java delegations β€” they don’t override driver behavior, proxy the JDBC layer, or touch internal state.


πŸ” Retry of Reads

int userCount = executor.execute(() -> {
    try (PreparedStatement ps = conn.prepareStatement("SELECT COUNT(*) FROM users");
         ResultSet rs = ps.executeQuery()) {
        rs.next();
        return rs.getInt(1);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
});

πŸ”§ Custom Retry Configuration

RetryConfig config = RetryConfig.custom()
    .maxAttempts(7)
    .waitDuration(Duration.ofMillis(250))
    .retryOnException(RetryableExecutor::isRetryable)
    .build();

RetryableExecutor executor = new RetryableExecutor(config);

πŸŒ€ Exponential Backoff

.intervalFunction(IntervalFunction.ofExponentialBackoff())

πŸ” Retry Behavior

Retries are automatically triggered for:

  • 40001: Serialization failures
  • Any 08XXX: Connection issues
  • 57P01: Admin shutdown

Backoff is managed via Resilience4j and is fully customizable.


πŸ§ͺ Integration Testing with CockroachDB

version: '3.8'
services:
  cockroach:
    image: cockroachdb/cockroach:latest
    command: start-single-node --insecure
    ports:
      - "26257:26257"
      - "8080:8080"
docker-compose up -d
./mvnw clean test

πŸ§ͺ Sample Integration Demo

Looking for a complete working example?

πŸ‘‰ Check out the cockroachdb-jdbc-wrapper-demo repository.

It shows how to:

  • Connect to CockroachDB using the JDBC wrapper
  • Use RetryableExecutor for clean, retryable read/write logic
  • Simulate 40001 errors for live retry demos
  • Run everything locally using Docker and Maven

Great for onboarding, testing, and CI!


πŸ› οΈ Build

This project includes the Maven Wrapper (mvnw) so you don't need to install Maven separately.

πŸ”¨ Build the Project

./mvnw clean package

This produces:

  • target/cockroachdb-jdbc-wrapper-0.1.0.jar β€” Slim JAR
  • target/cockroachdb-jdbc-wrapper-0.1.0-all.jar β€” Uber JAR with Resilience4j included

πŸ”§ Prerequisites

  • Java 21+ (JDK) to build the project
  • Java 17 or higher to run the JARs
  • Maven 3.9+ (optional β€” ./mvnw is included)
  • Docker (for optional demo environment)

Note: While the JAR is compatible with Java 17+, building from source requires JDK 21 due to Maven compiler target settings.

About

A lightweight, zero-maintenance Java library that wraps your existing PostgreSQL JDBC connection to automatically retry transient failures commonly encountered when using CockroachDB.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages