在下面的代码中,非事务性的createPerson函数调用事务性的createPersonTransaction.

IntelliJ强调了对createPersonTransactional的调用,说这是一个事务性的self 调用,不会在运行时导致事务.

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

当调用控制器createPerson函数时,日志(log)显示无论如何都要创建事务.

我一直认为,像这样的函数到函数调用会命中实际的函数,而不是Spring创建的代理函数,它用transactional代码包装了函数.

那么,IntelliJ的警告是错误的吗?我肯定过go 是这样的,但现在似乎不是了.

Spring Boot 3.2.2 BTW

@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)
    }

}

以下是显示正在进行的交易的日志(log):

2024-02-09T09:38:32.084Z DEBUG 5102 --- [nio-8081-exec-3] o.s.web.servlet.DispatcherServlet        : POST "/person", parameters={}
2024-02-09T09:38:32.084Z DEBUG 5102 --- [nio-8081-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.rosbug.PersonController#createPerson(PersonRequest)
2024-02-09T09:38:32.084Z DEBUG 5102 --- [nio-8081-exec-3] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2024-02-09T09:38:32.152Z DEBUG 5102 --- [nio-8081-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [PersonRequest(name=bert)]
2024-02-09T09:38:32.178Z DEBUG 5102 --- [nio-8081-exec-3] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(1455667122<open>)] for JPA transaction
2024-02-09T09:38:32.178Z DEBUG 5102 --- [nio-8081-exec-3] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2024-02-09T09:38:32.182Z DEBUG 5102 --- [nio-8081-exec-3] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@65c57510]
2024-02-09T09:38:32.283Z DEBUG 5102 --- [nio-8081-exec-3] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
2024-02-09T09:38:32.283Z DEBUG 5102 --- [nio-8081-exec-3] o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [SessionImpl(1455667122<open>)]
2024-02-09T09:38:32.305Z DEBUG 5102 --- [nio-8081-exec-3] o.s.orm.jpa.JpaTransactionManager        : Not closing pre-bound JPA EntityManager after transaction
2024-02-09T09:38:32.308Z DEBUG 5102 --- [nio-8081-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/xml', given [*/*] and supported [application/xml]
2024-02-09T09:38:32.320Z DEBUG 5102 --- [nio-8081-exec-3] m.m.a.RequestResponseBodyMethodProcessor : Writing [com.example.rosbug.Person@3b4eb178]
2024-02-09T09:38:32.340Z DEBUG 5102 --- [nio-8081-exec-3] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2024-02-09T09:38:32.341Z DEBUG 5102 --- [nio-8081-exec-3] o.s.web.servlet.DispatcherServlet        : Completed 200 OK

推荐答案

我一直认为像这样的函数对函数调用会命中 实际函数,而不是Spring创建的代理函数 它用事务性代码包装函数.

我认为这个假设仍然是正确的.当从同一个类中调用时,createPersonTransactional上的@Transactional仍然被"忽略"-您看到的事务来自存储库.

请提供更多记录事务详细信息的示例以进行确认(例如,在调用每个方法之前和之后打印一些日志(log)).我认为这将揭示该方法本身并未包装在事务中,而是您所看到的事务来自PersonRepository.save().没有关于PersonRepository的详细信息,所以我在这里只是猜测--但我猜它扩展了SimpleJpaRepository(从org.springframework.data.jpa.repository.support开始),其中有save个方法用@Transactional注释.

Kotlin相关问答推荐

在Kotlin中可以连接两个范围吗?

"Kotlin中的表达式

有没有办法在 jetpack compose 中将 TextField 密码点图标增加得更大?

为什么 <= 可以应用于 Int 和 Long,而 == 不能?

按钮无法在 Android Studio 上打开新活动

多个不同的指针输入

从 HashMap 检索时的 NPE,即使 containsKey() 在多线程环境中返回 true

如果不为空,则为 builder 设置一个值 - Kotlin

如何使用 Android CameraX 自动对焦

从 Java 调用 Kotlin 高阶函数

下拉通知面板时是否可以暂停Android中的任何视频(媒体播放器)应用程序?

kotlin 扩展属性的惰性初始化器中的这个引用

Gradle 同步失败:不支持的方法:KotlinPlatformContainer.supports()

验证和 DDD - kotlin 数据类

在 Kotlin 中实现 (/inherit/~extend) 注解

Android插件2.2.0-alpha1无法使用Kotlin编译

Android Jetpack导航,另一个主机片段中的主机片段

从命令行运行Java到Kotlin转换器?

有没有办法在Kotlin中设置一个私有常量

使用 Moshi/Retrofit2 访问深度嵌套的 JSON 数组