如何处理协同程序内的Spring事务?

问题描述 投票:1回答:1

众所周知,Spring事务与线程相关联:存在特定于正在进行的事务的线程本地。交易对协程背景一无所知。那么如果我想从协程中调用@Transactional方法怎么办呢:它安全吗?

想象一下,我们在JobProcessor bean中有一个处理作业列表的方法。每个作业都在async {}内处理。我希望在使用bean JobService的@Transactional方法成功或失败处理后更新数据库。

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) {...}
} 
spring kotlin transactions kotlinx.coroutines
1个回答
1
投票

首先,请记住使用@Transactional注释bean方法是不够的 - 确保启用声明式事务处理,例如通过将@EnableTransactionManagement添加到@Configuration类或在XML配置中使用<tx-annotation-driven />

关于你的问题:当从包含类的Spring bean之外调用它们时,执行使用@Transactional注释的Spring bean方法时,只会有一个事务上下文! Spring中的声明性事务依赖于Spring为@Transactional注释类创建的AOP代理类。在运行时,如果Spring bean A在Spring bean B上调用@Transactional方法,则调用将被AOP代理拦截,该代理透明地生成事务,调用Spring bean B的原始方法,然后提交或回滚此事务。

请记住:只有通过代理进入的外部方法调用才会被截获 - 任何自调用调用,如示例中调用@Transactional方法的this.process()方法this.success()this.failure()将不会启动任何事务 - 即使方法注释了@Transactional

© www.soinside.com 2019 - 2024. All rights reserved.