Skip to content

michaelbull/kotlin-coroutines-jdbc

Repository files navigation

kotlin-coroutines-jdbc

Maven Central CI License

A library for interacting with blocking JDBC drivers using Kotlin Coroutines.

Use of this library allows you to offload blocking JDBC calls to a dedicated CoroutineDispatcher (e.g. Dispatchers.IO), thus suspending your coroutine and freeing your thread for other work while waiting.

Installation

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.michael-bull.kotlin-coroutines-jdbc:kotlin-coroutines-jdbc:1.1.0")
}

Introduction

The primary higher-order function exposed by the library is the transaction function.

suspend inline fun <T> transaction(crossinline block: suspend () -> T): T

Calling this function with a specific suspending block will run the block in the context of a CoroutineTransaction.

Transactions cannot be nested. Calling transaction (or any of its variants) within an existing transaction will throw an IllegalStateException.

Starting a transaction will add a CoroutineTransaction to the current CoroutineContext. The transaction will either commit on success or rollback if an exception is thrown.

A transaction will establish a new Connection if an open one does not already exist in the active CoroutineContext. If the transaction does establish a new Connection, it will attempt to close it upon completion.

An active Connection is accessible via the currentConnection function, which can be used to prepare statements.

Transaction Variants

The library provides several transaction variants for different use cases:

  • transaction - Standard read-write transaction
  • readOnlyTransaction - Sets the connection to read-only mode before starting the transaction
  • isolatedTransaction - Sets a specific transaction isolation level before starting the transaction
  • isolatedReadOnlyTransaction - Combines read-only mode with a specific isolation level
// Standard transaction
transaction {
    // read-write operations
}

// Read-only transaction (useful for queries that don't modify data)
readOnlyTransaction {
    // read-only operations
}

// Transaction with specific isolation level
isolatedTransaction(Connection.TRANSACTION_SERIALIZABLE) {
    // operations with serializable isolation
}

// Read-only transaction with specific isolation level
isolatedReadOnlyTransaction(Connection.TRANSACTION_READ_COMMITTED) {
    // read-only operations with read committed isolation
}

Example

import com.github.michaelbull.jdbc.context.CoroutineDataSource
import com.github.michaelbull.jdbc.currentConnection
import com.github.michaelbull.jdbc.transaction
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.sql.DataSource

class Example(dataSource: DataSource) {

    private val scope = CoroutineScope(Dispatchers.IO + CoroutineDataSource(dataSource))
    private val customers = CustomerRepository()

    fun query() {
        scope.launchTransaction()
    }

    private fun CoroutineScope.launchTransaction() = launch {
        val customers = addThenFindAllCustomers()
        customers.forEach(::println)
    }

    private suspend fun addThenFindAllCustomers(): List<String> = transaction {
        customers.add("John Doe")
        customers.findAll()
    }
}

class CustomerRepository {

    suspend fun add(name: String) {
        currentConnection().prepareStatement("INSERT INTO customers VALUES (?)").use { stmt ->
            stmt.setString(1, name)
            stmt.executeUpdate()
        }
    }

    suspend fun findAll() = buildList<String> {
        urrentConnection().prepareStatement("SELECT name FROM customers").use { stmt ->
            stmt.executeQuery().use { rs ->
                while (rs.next()) {
                    add(rs.getString("name"))
                }
            }
        }
    }
}

Further Reading

Contributing

Bug reports and pull requests are welcome on GitHub.

License

This project is available under the terms of the ISC license. See the LICENSE file for the copyright information and licensing terms.

About

A library for interacting with blocking JDBC drivers using Kotlin Coroutines.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages