JetBrains / JetBrains/Exposed

Better API for nested transactions

Open
#1,360 0 comments 10 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
9.3k
Forks
798
Avg merge
4d 2h
Merged PRs (30d)
26

Description

Hello,

in our project we decided to go for Exposed (from mybatist). And go with Exposed and Spring Transaction API. But current impl of transaction manager does not work with `@Transactional(propagation = Propagation.REQUIRES_NEW)` and ` @Transactional(propagation = Propagation.NESTED)` issues [1263](https://github.com/JetBrains/Exposed/issues/1263) and [1264](https://github.com/JetBrains/Exposed/issues/1264). But we needed to use nested transactions.

So in the end we did drop Spring Transaction Api and went for `transaction { }` with `db.useNestedTransactions = true`.

Our project is not small one and as mentioned in wiki, unwanted usage of nested transactions may have performance impact.

Current approach from wiki
```
val db = Database.connect()
db.useNestedTransactions = true

transaction {
FooTable.insert{ it[id] = 1 }

var idToInsert = 0
transaction { // nested transaction
idToInsert++
FooTable.insert{ it[id] = idToInsert }
}
}
```

will work fine on small projects, but for bigger code bases those will lead to problems with unnecessary nested transactions. So I would like to start debate about some other approach how to create nested transaction. Mainly about - nested transaction should be created only by direct demand not by nesting `transaction { }` calls, because it can happen by function calls by mistake.

For now I am thinking about those 2 functions for our project (hope this logic is correct)
```
fun dbTransaction(block: Transaction.() -> T): T {
val currentTransaction = TransactionManager.currentOrNull()
//not in transaction -> get into one
return if (currentTransaction == null) {
transaction { block() }
} else {
//already in transaction so execute in there
block(currentTransaction)
}
}

fun nestedDbTransaction(block: Transaction.() -> T): T {
return transaction {
check(db.useNestedTransactions) { "Nested transactions are not enabled." }
block()
}
}
```
but it would be nice to have support for likewise behavior in lib itself.

It does not have to be new function, parameter `nestedTx: Boolean = false` or so would also do.

Thx for consideration,
V

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.