是否可以在 Spring Boot 中使用 @Transactional 和 kotlin 协程?

Posted

技术标签:

【中文标题】是否可以在 Spring Boot 中使用 @Transactional 和 kotlin 协程?【英文标题】:Is it possible to use @Transactional and kotlin coroutines in spring boot? 【发布时间】:2021-01-16 01:41:37 【问题描述】:

我有一个Spring boot项目,尝试使用@Transactional和协程,报错

org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException.

现在可以使用@Transactional 和协程了吗?

override suspend fun invoke() 
    val result = withContext(Dispatchers.IO)  deactivate() 
 

@Transactional
private suspend fun deactivate(): Int 
    //data base call 1
    //data base call 2
    // ...

【问题讨论】:

【参考方案1】:

@Transactional 方法调用期间,您不能启动在不同线程上执行事务性工作的协程。

@Transactional 导致代码被拦截。在deactivate()前后,会为你调用事务相关的代码。 因为协程可以在不同的线程上启动,它们将在这些事务调用之外启动。

相关 *** 主题:Spring - @Transactional - What happens in background?

【讨论】:

非常感谢。如果我需要使用事务和协程,是否有一些解决方法? 您可以调用协程并等待它,直到它在该函数中完成。【参考方案2】:

将方法包装在事务中的原因是为了确保该方法在数据库级别是原子的,并且当出现故障时,整个事务将被还原,就好像它从未发生过一样。

通过使用协程中断事务,如果您执行任何其他数据库操作,就会破坏方法的原子性,并且当出现故障时,协程的这些操作将不会被恢复。

希望大家在使用这个(反)模式时要小心!

【讨论】:

以上是关于是否可以在 Spring Boot 中使用 @Transactional 和 kotlin 协程?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 Spring(非 Boot)上使用 Testcontainers?

是否可以让Jackson ObjectMapper在Spring Boot应用程序中遵守JAXB XML注释?

是否有任何选项可以在 Spring Boot 中使用 Jackson 为 java.time.* 包注册一次 Serializer/Deserializer?

是否可以使用 Spring Boot 注释 @Value 从 application.properties 文件中获取 Map 值 [重复]

是否可以在 Spring Boot 应用程序中使用脚本创建数据库,并使用 flyway for postgres?如果是的话怎么办?

是否可以在 Spring Boot 中将 MongoDb 和 PostgreSql 用于同一模型?