kirill
kirill

Reputation: 47

Is it possible to use @Transactional and kotlin coroutines in spring boot?

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

Answers (3)

Bas
Bas

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

ByteWelder
ByteWelder

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

Related Questions