Skip to content

Commit

Permalink
Possible connection leak within SpringTransactionManager JetBrains#1355
Browse files Browse the repository at this point in the history
DatabaseConfig.explicitDialect param added
  • Loading branch information
Tapac authored and SchweinchenFuntik committed Oct 23, 2021
1 parent 5582478 commit 4440f45
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class Database private constructor(
}

val dialect by lazy {
dialects[vendor.lowercase()]?.invoke() ?: error("No dialect registered for $name. URL=$url")
config.explicitDialect ?: dialects[vendor.lowercase()]?.invoke() ?: error("No dialect registered for $name. URL=$url")
}

val version by lazy { metadata { version } }
Expand Down Expand Up @@ -207,11 +207,10 @@ class Database private constructor(
}

fun getDefaultIsolationLevel(db: Database): Int =
when (db.vendor) {
SQLiteDialect.dialectName -> Connection.TRANSACTION_SERIALIZABLE
OracleDialect.dialectName -> Connection.TRANSACTION_READ_COMMITTED
PostgreSQLDialect.dialectName -> Connection.TRANSACTION_READ_COMMITTED
PostgreSQLNGDialect.dialectName -> Connection.TRANSACTION_READ_COMMITTED
when (db.dialect) {
is SQLiteDialect -> Connection.TRANSACTION_SERIALIZABLE
is OracleDialect -> Connection.TRANSACTION_READ_COMMITTED
is PostgreSQLDialect -> Connection.TRANSACTION_READ_COMMITTED
else -> DEFAULT_ISOLATION_LEVEL
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jetbrains.exposed.sql

import org.jetbrains.exposed.sql.vendors.DatabaseDialect

const val DEFAULT_REPETITION_ATTEMPTS = 3

@Suppress("LongParameterList")
Expand All @@ -12,6 +14,7 @@ class DatabaseConfig private constructor(
val warnLongQueriesDuration: Long?,
val maxEntitiesToStoreInCachePerEntity: Int,
val keepLoadedReferencesOutOfTransaction: Boolean,
val explicitDialect: DatabaseDialect?
) {

class Builder(
Expand Down Expand Up @@ -57,7 +60,12 @@ class DatabaseConfig private constructor(
* within the entity that will allow to access them outside the transaction.
* Useful when [eager loading](https://github.com/JetBrains/Exposed/wiki/DAO#eager-loading) is used
*/
var keepLoadedReferencesOutOfTransaction: Boolean = false
var keepLoadedReferencesOutOfTransaction: Boolean = false,

/**
* Set the explicit dialect for a database. Can be useful when working with not supported dialects which have the same behavior as the one that Exposed supports
*/
var explicitDialect: DatabaseDialect? = null,
)

companion object {
Expand All @@ -71,7 +79,8 @@ class DatabaseConfig private constructor(
defaultRepetitionAttempts = builder.defaultRepetitionAttempts,
warnLongQueriesDuration = builder.warnLongQueriesDuration,
maxEntitiesToStoreInCachePerEntity = builder.maxEntitiesToStoreInCachePerEntity,
keepLoadedReferencesOutOfTransaction = builder.keepLoadedReferencesOutOfTransaction
keepLoadedReferencesOutOfTransaction = builder.keepLoadedReferencesOutOfTransaction,
explicitDialect = builder.explicitDialect
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.StdOutSqlLogger
import org.jetbrains.exposed.sql.Transaction
import org.jetbrains.exposed.sql.addLogger
import org.jetbrains.exposed.sql.exposedLogger
import org.jetbrains.exposed.sql.statements.api.ExposedConnection
import org.jetbrains.exposed.sql.statements.jdbc.JdbcConnectionImpl
import org.jetbrains.exposed.sql.transactions.TransactionInterface
Expand Down Expand Up @@ -97,7 +98,13 @@ class SpringTransactionManager(
private fun initTransaction(): Transaction {
val connection = (TransactionSynchronizationManager.getResource(obtainDataSource()) as ConnectionHolder).connection

val transactionImpl = SpringTransaction(JdbcConnectionImpl(connection), db, defaultIsolationLevel, currentOrNull())
val transactionImpl = try {
SpringTransaction(JdbcConnectionImpl(connection), db, defaultIsolationLevel, currentOrNull())
} catch (e: Exception) {
exposedLogger.error("Failed to start transaction. Connection will be closed.", e)
connection.close()
throw e
}
TransactionManager.resetCurrent(this)
return Transaction(transactionImpl).apply {
TransactionSynchronizationManager.bindResource(this@SpringTransactionManager, this)
Expand Down

0 comments on commit 4440f45

Please sign in to comment.