From 621dc5b939b03c0f2396073c17f7ab5a7022816c Mon Sep 17 00:00:00 2001 From: "Andrey.Tarashevskiy" Date: Sun, 28 Nov 2021 20:26:01 +0300 Subject: [PATCH] Bug when calling TransactionManager.closeAndUnregister from a different Thread / Fix #2 #1387 --- .../sql/transactions/TransactionApi.kt | 5 +++- .../jetbrains/exposed/sql/tests/h2/H2Tests.kt | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/transactions/TransactionApi.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/transactions/TransactionApi.kt index 6e7dbaf14e..7fb430f079 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/transactions/TransactionApi.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/transactions/TransactionApi.kt @@ -69,8 +69,11 @@ interface TransactionManager { if (defaultDatabase == null) { currentThreadManager.remove() } + if (!registeredDatabases.containsKey(database)) { + databases.push(database) + } + registeredDatabases[database] = manager - databases.push(database) } @Synchronized fun closeAndUnregister(database: Database) { diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/h2/H2Tests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/h2/H2Tests.kt index 57941d4e85..766e7ab017 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/h2/H2Tests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/h2/H2Tests.kt @@ -4,7 +4,11 @@ import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.tests.DatabaseTestsBase import org.jetbrains.exposed.sql.tests.TestDB import org.jetbrains.exposed.sql.tests.shared.assertEquals +import org.jetbrains.exposed.sql.transactions.TransactionManager +import org.jetbrains.exposed.sql.transactions.transactionManager import org.junit.Test +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit class H2Tests : DatabaseTestsBase() { @@ -69,6 +73,29 @@ class H2Tests : DatabaseTestsBase() { } } + @Test + fun closeAndUnregister() { + withDb(TestDB.H2) { testDB -> + val orignalManager = TransactionManager.manager + val db = requireNotNull(testDB.db) { "testDB.db cannot be null" } + try { + TransactionManager.registerManager( + db, + WrappedTransactionManager(db.transactionManager) + ) + Executors.newSingleThreadExecutor().apply { + submit { TransactionManager.closeAndUnregister(db) } + .get(1, TimeUnit.SECONDS) + }.shutdown() + } finally { + TransactionManager.registerManager(db, orignalManager) + } + } + } + + class WrappedTransactionManager(val transactionManager: TransactionManager) : + TransactionManager by transactionManager + object Testing : Table("H2_TESTING") { val id = integer("id").autoIncrement() // Column val string = varchar("string", 128)