This will be a fast-paced sequence of tips for using Kotlin Coroutines with Spring.

Tip 1

If you need transactions, don’t forgot to use the @EnableTransactionManagement annotation.

Tip 2

Probably you do not want to .subscribe to your Mono/Flux instances like in the example below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

  suspend fun handleSomeRequest(request: ServerRequest): ServerResponse {
    
    val someNewEntity = SomeEntity()
    someEntityRepository.save(someNewEntity).subscribe()
    
    // some other stuff...

  }

Just use coroutine’s .awaitSingle() instead.

Tip 3

For some reason, as of today (Spring Framework v5.3.3 / Spring Boot v2.4.2), Kotlin Coroutines reactive DSL doesn’t work with Spring’s declarative transactions (@Transactional annotation).

This exception won’t rollback the current transaction:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import kotlinx.coroutines.reactor.mono

//...
  @Transactional
  suspend fun exampleMonoDSLThrow(): Mono<Void> {
    return mono {
      val employee = Employee(name = faker.artist().name())
      val savedArtist = repository.save(employee).awaitSingle()
      throw RuntimeException("createMonoThrow")
    }
  }
//...

On the other hand, the kotlinx.coroutines.flow.flow works fine. Also, kotlinx.coroutines.reactor.flux doesn’t work.