{"id":21068098,"url":"https://github.com/simao/async-db","last_synced_at":"2025-12-27T21:47:22.904Z","repository":{"id":45357381,"uuid":"395679454","full_name":"simao/async-db","owner":"simao","description":"non blocking API for jdbc","archived":false,"fork":false,"pushed_at":"2022-03-29T13:01:15.000Z","size":78,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-20T21:25:38.764Z","etag":null,"topics":["jdbc","scala","sql"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simao.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-08-13T14:14:17.000Z","updated_at":"2022-11-28T14:39:03.000Z","dependencies_parsed_at":"2022-09-26T22:10:19.458Z","dependency_job_id":null,"html_url":"https://github.com/simao/async-db","commit_stats":null,"previous_names":["simao/anorm-async"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simao%2Fasync-db","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simao%2Fasync-db/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simao%2Fasync-db/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simao%2Fasync-db/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simao","download_url":"https://codeload.github.com/simao/async-db/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243510123,"owners_count":20302294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jdbc","scala","sql"],"created_at":"2024-11-19T18:14:22.573Z","updated_at":"2025-12-27T21:47:22.852Z","avatar_url":"https://github.com/simao.png","language":"Scala","readme":"# async-db - non blocking API for jdbc database connections\n\n[![Maven Central](https://img.shields.io/maven-central/v/eu.0io/async-db_2.13)](https://mvnrepository.com/artifact/eu.0io/async-db) [![Continuous integration](https://github.com/simao/async-db/actions/workflows/ci.yml/badge.svg)]()\n\nJDBC is commonly used in Scala to access databases, however, JDBC uses blocking IO whenever it access the database, blocking the current thread. therefore developers need to be careful when using JDBC in an asynchronous application. \n\nasync-db is a thin wrapper around JDBC that includes a preconfigured thread pool and provides a non blocking API to connect to a database, using`Future`.\n\nThe thread pool is a simpler version of the thread pool used by [slick](https://github.com/slick/slick/):\n\n- It uses a blocking queue to queue requests, which are processed FIFO\n\n- The queue is limited and this limit is configurable, once the queue is full the api caller requests will be rejected\n\n- The threads created are daemon threads\n\n- One thread will be created per database connection, so that jdbc blocking calls do not affect other connections.\n\n[Hikari-CP](https://github.com/brettwooldridge/HikariCP) is used to manage the connection pool.\n\n## How to use\n\nGet `\u003cversion\u003e` from the maven central badge above.\n\n### With sbt\n\n```\nlibraryDependencies += \"eu.0io\" %% \"async-db\" % \"\u003cversion\u003e\"\n```\n\n### With mill\n\n```\nivy\"eu.0io::async-db:\u003cversion\u003e\"\n```\n\nYou'll also need to add the JDBC drivers for the database you need to connect to.\n\n## Configure\n\nCreate a configuration for your database and thread pools in `application.conf`:\n\nCreate or edit an `application.conf` in your classpath with the following configurations:\n\n\n```\nyour-app {\n  database {\n    jdbcurl = \"jdbc:postgresql://host:port/schema\"\n\n    jdbc-properties = {\n      reWriteBatchedInserts = true # You can put any property specific to your JDBC connector here\n    }\n\n    thread-pool = {\n      queueSize = 1000\n    }\n\n    db-pool = {\n      properties = { // Hikari CP specific pool configurations, see https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby\n        registerMbeans = true\n        maximumPoolSize = 10\n        minimumIdle = 10\n      }\n    }\n  }\n}\n```\n\n### Use\n\nCreate a `Database`:\n\n```scala\nimport com.typesafe.config.ConfigFactory\nimport eu._0io.async_db.Database\n\nval config = ConfigFactory.load().getConfig(\"your-app.database\")\nimplicit lazy val db = Database.fromConfig(config)\n```\n\nYou can then share this `db` instance on your application and execute SQL queries:\n\n```scala\nval id  = db.withConnection { c: Connection =\u003e\n  // Your jdbc code to use `Connection`\n}\n\n// id has type Future[_]\n```\n\nRun transactions with `withTransaction`:\n\n```scala\nval id  = db.withTransaction { c =\u003e\n  // Your jdbc code to use `Connection`\n}\n```\n\nThe transactions will be committed if the function passed as argument succeeds or is rollbacked if an exceptions is thrown. For finer control of the transaction behavior, you can use `withConnection` directly.\n\n## Monitoring\n\nBoth `async-db` and `hikari-cp` will publish metrics using [dropwizard metrics](https://metrics.dropwizard.io/4.2.0/). This can be enabled by passing a metrics collector when initializing a `Database`:\n\n```scala\nval metricRegistry = new MetricRegistry\nimplicit lazy val db = Database.fromConfig(config, Option(metricRegistry))\n```\n\nYou can then enable the dropwizard reporters, for example for the console reporter:\n\n```scala\nval reporter = ConsoleReporter.forRegistry(metricRegistry).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build\nreporter.start(10, TimeUnit.SECONDS)\n```\n\nWill report:\n\n```\n-- Gauges ----------------------------------------------------------------------\nHikariPool-1.pool.ActiveConnections\n             value = 0\nHikariPool-1.pool.IdleConnections\n             value = 10\nHikariPool-1.pool.MaxConnections\n             value = 10\nHikariPool-1.pool.MinConnections\n             value = 10\nHikariPool-1.pool.PendingConnections\n             value = 0\nHikariPool-1.pool.TotalConnections\n             value = 10\nasync-db.db.HikariPool-1.io-thread-pool.active-count\n             value = 0\nasync-db.db.HikariPool-1.io-thread-pool.core-pool-size\n             value = 10\nasync-db.db.HikariPool-1.io-thread-pool.pool-size\n             value = 8\nasync-db.db.HikariPool-1.io-thread-pool.queue-size\n             value = 0\nasync-db.db.HikariPool-1.io-thread-pool.task-count\n             value = 8\n\n-- Histograms ------------------------------------------------------------------\nHikariPool-1.pool.ConnectionCreation\n             count = 9\n               min = 4\n               max = 40\n              mean = 9.78\n            stddev = 10.81\n            median = 6.00\n              75% \u003c= 8.00\n              95% \u003c= 40.00\n              98% \u003c= 40.00\n              99% \u003c= 40.00\n            99.9% \u003c= 40.00\nHikariPool-1.pool.Usage\n             count = 9\n               min = 2\n               max = 116\n              mean = 27.56\n            stddev = 39.35\n            median = 4.00\n              75% \u003c= 34.00\n              95% \u003c= 116.00\n              98% \u003c= 116.00\n              99% \u003c= 116.00\n            99.9% \u003c= 116.00\n\n-- Meters ----------------------------------------------------------------------\nHikariPool-1.pool.ConnectionTimeoutRate\n             count = 0\n         mean rate = 0.00 events/second\n     1-minute rate = 0.00 events/second\n     5-minute rate = 0.00 events/second\n    15-minute rate = 0.00 events/second\n\n-- Timers ----------------------------------------------------------------------\nHikariPool-1.pool.Wait\n             count = 9\n         mean rate = 30.69 calls/second\n     1-minute rate = 0.00 calls/second\n     5-minute rate = 0.00 calls/second\n    15-minute rate = 0.00 calls/second\n               min = 0.02 milliseconds\n               max = 0.22 milliseconds\n              mean = 0.06 milliseconds\n            stddev = 0.06 milliseconds\n            median = 0.04 milliseconds\n              75% \u003c= 0.05 milliseconds\n              95% \u003c= 0.22 milliseconds\n              98% \u003c= 0.22 milliseconds\n              99% \u003c= 0.22 milliseconds\n            99.9% \u003c= 0.22 milliseconds\n```\n\n## Build and running tests\n\nYou will need [mill](https://com-lihaoyi.github.io/mill/mill/Intro_to_Mill.html) installed.\n\nTo run tests you'll need a postgres instance:\n\n```\ndocker run --name async-db -p 5432:5432 -e POSTGRES_PASSWORD=root -e POSTGRES_USER=async-db -d postgres:13.3-alpine\n```\n\nThen run tests:\n\n`mill async-db[_].test`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimao%2Fasync-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimao%2Fasync-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimao%2Fasync-db/lists"}