diff --git a/CHANGELOG.md b/CHANGELOG.md index 401f6651..fa4faf12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,13 @@ # Unreleased -* json: fix TSGenerator on Windows +* server: `Server(InetSocketAddress(0))` can now be used to bind to any available port. +* server: make idle restarts quick #96 +* server: initialize `HttpExchange.pathParams` even no route is matched (404), for decorators #82 * jdbc: between operator introduced with open and closed ranges, also in and notIn * jdbc: @NoTransaction can now be used on jobs * jdbc: fixed usage of multiple different DataSources when there is an active transaction +* jdbc: allow calling of `PooledConnection.close()` multiple times #80 +* json: fix TSGenerator on Windows * json: TSGenerator will now use more type-safe string template types for java.time classes, e.g. `${number}-${number}-${number}` instead of `string` -* server: `Server(InetSocketAddress(0))` can now be used to bind to any available port. -* server: make idle restarts quick #96 -* server: initialize `HttpExchange.pathParams` even no route is matched (404), for decorators #82 * jackson: serialize enums using their toString() method by default, this fixes `openapi` module usage with `jackson` #88 * liquibase: do not close jdbc connection if it was passed by user #81 diff --git a/jdbc/src/PooledDataSource.kt b/jdbc/src/PooledDataSource.kt index c523fdf6..6714e6df 100644 --- a/jdbc/src/PooledDataSource.kt +++ b/jdbc/src/PooledDataSource.kt @@ -99,12 +99,15 @@ class PooledDataSource( internal fun checkBySetApplicationName() { applicationName = currentThread().name } - override fun close() = try { - used -= this - if (!conn.autoCommit) conn.rollback() - available += this - } catch (e: SQLException) { - log.warn("Failed to return $this: $e") + override fun close() { + try { + if (used.remove(this) != null) { + if (!conn.autoCommit) conn.rollback() + available += this + } else log.warn("Trying to close already returned $this") + } catch (e: SQLException) { + log.warn("Failed to return $this: $e") + } } internal fun reallyClose() = try { diff --git a/jdbc/test/PooledDataSourceTest.kt b/jdbc/test/PooledDataSourceTest.kt index d3d94e5f..88fa0cf2 100644 --- a/jdbc/test/PooledDataSourceTest.kt +++ b/jdbc/test/PooledDataSourceTest.kt @@ -86,4 +86,21 @@ class PooledDataSourceTest { expect(pool.available).toHaveSize(0) expect(pool.used.keys).toHaveSize(0) } + + @Test fun `close same connection multiple times`() { + val conn = pool.connection + expect(pool.used.keys).toHaveSize(1) + expect(pool.available).toHaveSize(0) + + conn.close() + conn.close() + conn.close() + + expect(pool.used.keys).toHaveSize(0) + expect(pool.available).toHaveSize(1) + + val conn2 = pool.connection + expect(pool.connection).notToEqual(conn2) + expect(pool.connection).notToEqual(conn2) + } }