为什么非事务方法调用对事务方法调用仍然在Spring的事务中运行?

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

在下面的代码中,非事务性的 createPerson 函数调用了事务性的 createPersonTransactional。

IntelliJ 突出显示了

createPersonTransactional
的调用,表示这是事务性自调用,不会导致运行时发生事务。

这两个函数都在从控制器调用的服务中。

当调用控制器

createPerson
函数时,日志显示无论如何都会创建一个事务。

我一直认为像这样的函数到函数的调用会击中实际函数,而不是 spring 创建的用事务代码包装函数的代理函数。

那么 IntelliJ 的警告是错误的吗?我确信过去是这样,但现在似乎不再是这样了。

Spring Boot 3.2.2 顺便说一句

@Service
class PersonService(val personRepository: PersonRepository) {

    fun createPerson(personRequest: PersonRequest): Person {
        return createPersonTransactional(personRequest)
    }

    @Transactional
    fun createPersonTransactional(personRequest: PersonRequest): Person {
        val person = Person(name = personRequest.name)
        personRepository.save(person)
        return person
    }
}

interface PersonRepository : JpaRepository<Person, String>


@RestController
class PersonController(
    private val personService: PersonService
) {
    @PostMapping("/person", produces = [MediaType.APPLICATION_XML_VALUE])
    fun createPerson(@RequestBody personRequest: PersonRequest): Person {
        return personService.createPerson(personRequest)
    }

}
spring spring-boot kotlin spring-data-jpa
1个回答
0
投票

我一直认为像这样的函数到函数的调用会成功 实际函数,而不是 spring 创建的代理函数 它用事务代码包装了该函数。

我想说这个假设仍然是正确的。当从同一个类中调用时,

@Transactional
上的
createPersonTransactional
仍然被“忽略” - 您看到的事务来自存储库。

请提供更多示例,记录交易详细信息以进行确认(例如,在调用每个方法之前和之后打印一些日志)。我认为这将揭示该方法本身并未包含在事务中,但您看到的事务来自

PersonRepository.save()
。没有关于 PersonRepository 的详细信息,所以我只是在这里猜测 - 但我猜它扩展了
SimpleJpaRepository
(来自
org.springframework.data.jpa.repository.support
),它具有用
save
注释的
@Transactional
方法。

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