It is known that Spring transactions are tied to threads: there are thread locals specific for an ongoing transaction. And transactions know nothing about coroutine context. So what if I would like to call a @Transactional method from inside a coroutine: is it safe?
Imagine we have a method inside JobProcessor bean processing a job list. Each job is processed inside async{}. And I would like to update DB after every successful or failed processing using @Transactional methods of bean JobService.
class JobProcessor {
fun process(jobs: List<MyJob>) =
jobs.map { job ->
async {
try {
....//processing
jobService.success(job)
} catch (t: Throwable) {
jobService.failure(job)
}
}
}
class JobService {
@Transactional
fun success(job: MyJob) {...}
@Transactional
fun failure(job: MyJob) {...}
}
First, please keep in mind that annotating bean methods with @Transactional
will not suffice - make sure you enabled declarative transaction handling, e.g. by adding @EnableTransactionManagement
to a @Configuration
class or by using <tx-annotation-driven />
in XML config.
Regarding your question: There will only be a transactional context while executing Spring bean methods annotated with @Transactional
when they are being invoked from a Spring bean outside of their containing class! Declarative transactions in Spring rely on AOP proxy classes being created for the @Transactional
annotated classes by Spring. At runtime if a Spring bean A calls a @Transactional
method on a Spring bean B, the call will be intercepted by an AOP proxy that transparently spawns a transaction, calls the original method of Spring bean B and commits or rollbacks this transaction afterwards.
Remember: Only external method calls that come in through the proxy will be intercepted – any self-invocation calls, as in your example this.process() calling @Transactional
methods this.success()
or this.failure()
will not start any transaction – even if the method is annotated with @Transactional
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With