gpt4 book ai didi

java - Spring 事务管理是否与 Spring WebFlux 一起使用?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:31:11 28 4
gpt4 key购买 nike

Spring 对 RDBMS 事务管理的支持在 Spring WebFlux 中是否也有效?

例如,假设配置正确,使用 @Transactional 注解的方法是否会使用 Spring 事务管理器并在发生错误时回滚事务?

如果事务管理确实有效,则必须有一个 @Transactional 方法实际throw 和异常,或者必须 MonoFlux 返回类型发出错误信号?

我知道 JDBC 本质上是阻塞的,因此任何 JDBC 操作都必须从阻塞桥接到 react 桥,反之亦然。

Spring 事务管理器通过使用 ThreadLocal(对吗?)来工作,我假设它不会在 Reactor 环境中工作,因为 Reactor 对线程很节省,并且单个线程可以换出一个工作单元为另一个工作单元,而第一个工作单元正在等待 I/O。我知道 Reactor 有 Context 对象,它在概念上类似于 ThreadLocal(对吗?),但我还没有看到任何文档提到该事务使用它。此外,事务中发生的所有 JDBC 操作都必须使用相同的 Connection,这在响应式(Reactive)上下文中可能很难做到。

我的组织有使用 WebFlux 和 Cassandra 的经验,但 Cassandra 有一个原生的响应式驱动程序。

谢谢!

最佳答案

编辑:此答案对于 Spring Framework 5.2 M2 及更高版本不再有效。看这个article .感谢@Florent Dupont 提到这一点。

据我所知,Spring 标准事务管理不适用于 WebFlux。

使用@Transactional 将不起作用,因为当调用带注释的方法时,事务机制会将事务状态保存在调用线程的ThreadLocal 中。正如您自己所说,这是行不通的。它阻止并共享状态。

但是,您可以使用 .runOn(Schedulers.parallel()) 将阻塞代码发送到另一个线程。这样您就可以拥有一个带有可阻塞线程的线程池,您可以将其配置为与数据库连接池具有相同的大小。

但即便如此,您仍然不能依赖 @Transactional,因为线程池重用线程的方式。在标准的 Servlet 架构中,每个 HTTP 请求都有一个线程。当响应被发回时,线程停止,从而关闭事务。但在这种情况下,Reactor 调度程序不会关闭线程并将它们重新用于其他事件。因此,即使您可以阻止,您仍然会遇到与以前相同的问题。

您确实有您提到的 Context 选项,我认为这适用于 Mono。我不确定它是否适用于 Flux(我认为 Flux 中的所有事件共享相同的上下文,这是你不想要的)。

另一种选择是使用带有 T1 作为业务对象和 T2 事务上下文的 Touple2。不过,我不推荐这样做,因为您将业务逻辑与技术内容混合在一起,这会使事情变得过于复杂。

我最好的选择是自己进行事务/连接管理:

  1. 获取数据库连接
  2. 打开交易
  3. 做阻塞 IO 的事情
  4. 关闭TX
  5. 关闭/释放数据库连接

全部在阻塞线程上的一个代码块中。

这样会更安全(无泄漏)并且更容易理解。此外,由于基本上所有事情都是您自己完成的,因此您可以选择最适合您的场景的错误处理类型。

关于java - Spring 事务管理是否与 Spring WebFlux 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53934357/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com