I upgraded to Spring Boot 2.4 and Spring 5.3 in my Kotlin Web MVC project after seeing:
Support for @Transactional suspending functions (Kotlin Coroutines)
This transactional support, though, is not working for me in my project where I'm using jdbcTemplate
everywhere. Here's an example
An @Controller
suspending endpoint:
@PostMapping("/orders")
suspend fun saveOrder(@RequestBody orderRequest: OrderRequest): ResponseEntity<Order>{
val order = orderService.saveOrder(orderRequest)
// ...
}
Service:
@Transactional
@Service
OrderServiceImpl(): OrderService{
override suspend fun orderService(request: OrderRequest): Order{
// a mix of WebClient external service calls and calls to dao's that do coroutine jdbc in the `withContext(Dispatchers.IO)`
}
}
In a simple test, my DB calls are not in the same physical transaction. After looking more closely at at this issue, I will only get the @Transactional
support if the determined TransactionManager
is an instance of ReactiveTransactionManager
When debugging TransactionAspectSupport.invokeWithinTransaction
, I always get back the JdbcTransactionManager
. Is it not possible to use declarative transactions in Web MVC with coroutines as I've described? I had assumed this enhancement took to managing the ThreadLocal
based reference to the open transaction and added it to the current CoroutineContext
but that isn't the case for me.
If it's not possible, then what are the caveats around this @Transactional
coroutine support? Must I be using Spring WebFlux? Is there a requirement around the return type?
If there's an enhancement to be made here, I'd be happy to take a stab at it once I better understand what the desired state of this is.
Comment From: mistahenry
@sdeleuze whenever you have a chance, could you please provide some clarity here as to what's expected/possible and if there's an enhancement to be made here to allow coroutines to work with @Transactional
in the way I've described?
It's hard for me to tell whether I'm encountering a bug, something unsupported, or something not yet supported.
Comment From: sdeleuze
Coroutines are leveraging the Reactive transaction support, as a consequence they are not designed to work with thread-bound transactions. So Coroutines transactions should be used with WebFlux and R2DBC, not WebMVC and JDBC.