Add additional transactionality check. ()

* Add additional transactionality check.

* Fix logic
This commit is contained in:
Tudor Malene 2019-01-09 21:13:06 +00:00 committed by GitHub
parent 82010fbb3e
commit 60388a7a45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 7 deletions
node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence

@ -60,15 +60,19 @@ enum class TransactionIsolationLevel {
val jdbcValue: Int = java.sql.Connection::class.java.getField(jdbcString).get(null) as Int val jdbcValue: Int = java.sql.Connection::class.java.getField(jdbcString).get(null) as Int
} }
internal val _prohibitDatabaseAccess = ThreadLocal.withInitial { false }
private val _contextDatabase = InheritableThreadLocal<CordaPersistence>() private val _contextDatabase = InheritableThreadLocal<CordaPersistence>()
var contextDatabase: CordaPersistence var contextDatabase: CordaPersistence
get() = _contextDatabase.get() ?: error("Was expecting to find CordaPersistence set on current thread: ${Strand.currentStrand()}") get() {
require(_prohibitDatabaseAccess.get() != true) { "Database access is disabled in this context." }
return _contextDatabase.get() ?: error("Was expecting to find CordaPersistence set on current thread: ${Strand.currentStrand()}")
}
set(database) = _contextDatabase.set(database) set(database) = _contextDatabase.set(database)
private val _prohibitDatabaseAccess = ThreadLocal.withInitial { false }
/** /**
* The logic in the [block] will be prevented from opening a database transaction. * The logic in the [block] will be prevented from opening a database transaction.
* Also will not be able to access database resources ( Like the context transaction or the [contextDatabase] ).
*/ */
fun <T> withoutDatabaseAccess(block: () -> T): T { fun <T> withoutDatabaseAccess(block: () -> T): T {
val oldValue = _prohibitDatabaseAccess.get() val oldValue = _prohibitDatabaseAccess.get()
@ -131,8 +135,8 @@ class CordaPersistence(
private val liveTransactions = ConcurrentHashMap<UUID, DatabaseTransaction>() private val liveTransactions = ConcurrentHashMap<UUID, DatabaseTransaction>()
fun newTransaction(isolation: TransactionIsolationLevel = defaultIsolationLevel): DatabaseTransaction { fun newTransaction(isolation: TransactionIsolationLevel = defaultIsolationLevel): DatabaseTransaction {
if(_prohibitDatabaseAccess.get()){ if (_prohibitDatabaseAccess.get()) {
throw IllegalAccessException("Database access is not allowed in the current context.") throw IllegalAccessException("Database access is not allowed in the current context.")
} }
val outerTransaction = contextTransactionOrNull val outerTransaction = contextTransactionOrNull
return DatabaseTransaction(isolation.jdbcValue, contextTransactionOrNull, this).also { return DatabaseTransaction(isolation.jdbcValue, contextTransactionOrNull, this).also {

@ -10,11 +10,13 @@ import java.util.UUID
import javax.persistence.EntityManager import javax.persistence.EntityManager
fun currentDBSession(): Session = contextTransaction.session fun currentDBSession(): Session = contextTransaction.session
private val _contextTransaction = ThreadLocal<DatabaseTransaction>() private val _contextTransaction = ThreadLocal<DatabaseTransaction>()
var contextTransactionOrNull: DatabaseTransaction? var contextTransactionOrNull: DatabaseTransaction?
get() = _contextTransaction.get() get() = if (_prohibitDatabaseAccess.get() == true) throw IllegalAccessException("Database access is disabled in this context.") else _contextTransaction.get()
set(transaction) = _contextTransaction.set(transaction) set(transaction) = _contextTransaction.set(transaction)
val contextTransaction get() = contextTransactionOrNull ?: error("Was expecting to find transaction set on current strand: ${Strand.currentStrand()}") val contextTransaction
get() = contextTransactionOrNull ?: error("Was expecting to find transaction set on current strand: ${Strand.currentStrand()}")
class DatabaseTransaction( class DatabaseTransaction(
isolation: Int, isolation: Int,