在下面的代码中,非事务性的 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 创建的代理函数 它用事务代码包装了该函数。
我想说这个假设仍然是正确的。当从同一个类中调用时,
@Transactional
上的createPersonTransactional
仍然被“忽略” - 您看到的事务来自存储库。
请提供更多示例,记录交易详细信息以进行确认(例如,在调用每个方法之前和之后打印一些日志)。我认为这将揭示该方法本身并未包含在事务中,但您看到的事务来自
PersonRepository.save()
。没有关于 PersonRepository 的详细信息,所以我只是在这里猜测 - 但我猜它扩展了 SimpleJpaRepository
(来自 org.springframework.data.jpa.repository.support
),它具有用 save
注释的 @Transactional
方法。