Reputation: 47
I have a project on Spring boot and tried to use @Transactional and coroutines and got an error
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException.
Is it possible to use @Transactional and coroutines now?
override suspend fun invoke() {
val result = withContext(Dispatchers.IO) { deactivate() }
}
@Transactional
private suspend fun deactivate(): Int {
//data base call 1
//data base call 2
// ...
}
Upvotes: 4
Views: 9927
Reputation: 51
Since version 5.3.0
, support for suspending functions annotated with @Transactional
has been added
Release notes: https://github.com/spring-projects/spring-framework/releases/tag/v5.3.0
Commit:
https://github.com/spring-projects/spring-framework/commit/5429c7afebaa3255ea80197224023c29c7d552ec
And since version v6.1.0-M5, compatibility of suspending functions with Spring AOP
has been added:
https://github.com/spring-projects/spring-framework/releases/tag/v6.1.0-M5
Commit:
https://github.com/spring-projects/spring-framework/commit/c8169e5cad0bd616e251aa9c004eb2cdca081a59
Issue:
https://github.com/spring-projects/spring-framework/issues/22462
Upvotes: 0
Reputation: 3
The reason to wrap a method in a transaction is to ensure that the method is atomic at a database level, and when there is a failure the whole transaction is reverted as if it never happened.
By breaking out of the transaction, using coroutines, you break the atomicity of the method if you do any other database actions, and when there is a failure those actions of the coroutine will not be reverted.
I hope you will be careful when using this (anti-) pattern!
Upvotes: 0
Reputation: 5604
You can't start coroutines that do transactional work on a different thread during a @Transactional
method call.
@Transactional
leads to code being intercepted. Before and after deactivate()
, the transaction-related code will be called for you.
Because the coroutines could be launched on a different thread, they will be launched outside of these transaction calls.
Relevant StackOverflow topic: Spring - @Transactional - What happens in background?
Upvotes: 3