You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After using TransactionManager.closeAndUnregister(db) the thread becomes completely unusable for using any other database.
Approximate reproduction steps:
Make a database through Database.connect() in main thread
Use this database in a thread pool (threads 1, 2, 3)
Use TransactionManager.closeAndUnregister in last task (let's say, thread 1)
Now create another database through Database.connect() in main thread
Try to use this new database through the thread 1 of thread pool
This is what you get:
java.lang.IllegalStateException: Please call Database.connect() before using this code
at org.jetbrains.exposed.sql.transactions.NotInitializedManager.currentOrNull(TransactionApi.kt:38) ~[exposed-core-0.37.3.jar!/:na]
at org.jetbrains.exposed.sql.transactions.TransactionManager$Companion.currentOrNull(TransactionApi.kt:108) ~[exposed-core-0.37.3.jar!/:na]
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$transaction$1.invoke(ThreadLocalTransactionManager.kt:136) ~[exposed-core-0.37.3.jar!/:na]
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:223) ~[exposed-core-0.37.3.jar!/:na]
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:135) ~[exposed-core-0.37.3.jar!/:na]
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:132) ~[exposed-core-0.37.3.jar!/:na]
The text was updated successfully, but these errors were encountered:
In TransactionManager.closeAndUnregister there is following statement:
val manager = registeredDatabases[database]
manager?.let {
registeredDatabases.remove(database)
databases.remove(database)
currentDefaultDatabase.compareAndSet(database, null)
if (currentThreadManager.get() == it) { // <-------- this one
currentThreadManager.remove()
}
}
it calls currentThreadManager.get(). If current thread has this thread local removed (very common situation when there's no current transaction), it will try to re-initialize it. And will fail, because both databases and registeredDatabases are empty now, so it will default to NotInitializedManager, which will stick and destroy any transaction(...) call that you may try in this thread afterwards.
Wrapping it into transaction(...) won't help, it will fail to finish transaction as there won't be any databases/managers left after the closeAndUnregister call.
Kaned1as
changed the title
closeAndUnregister somehow makes a thread local transaction manager completely deadcloseAndUnregister makes a thread local transaction manager completely dead
Mar 17, 2022
After using
TransactionManager.closeAndUnregister(db)
the thread becomes completely unusable for using any other database.Approximate reproduction steps:
Database.connect()
in main threadTransactionManager.closeAndUnregister
in last task (let's say, thread 1)Database.connect()
in main threadThis is what you get:
The text was updated successfully, but these errors were encountered: