Spring事务管理可以与Spring WebFlux一起使用吗?
Spring对RDBMS事务管理的支持在Spring WebFlux中是否也起作用?
例如,假设配置正确,带有@Transactional
注释的方法是否会使用Spring事务管理器并在发生错误时回滚事务?
如果事务管理确实起作用,那么@Transactional
方法是否必须实际throw
和异常,或者必须是Mono
或Flux
返回类型发出错误信号?
我知道JDBC本质上是阻塞的,因此任何JDBC操作都必须从阻塞过渡到反应性,反之亦然。
Spring事务管理器通过使用ThreadLocal
(对吗?)工作,我假设它在Reactor环境中不起作用,因为Reactor在线程方面很节俭,并且在第一个线程正在等待时,一个线程可以将一个工作单元换成另一个工作单元在I
/
O上。我知道Reactor的Context
对象在概念上类似于ThreadLocal
(对吗?),但是我还没有看到任何文档提到该事务使用了它。另外,事务中发生的所有JDBC操作都必须使用相同的操作,Connection
这在响应式上下文中可能很难做到。
我的组织具有WebFlux和Cassandra的经验,但是Cassandra具有本机响应式驱动程序。
谢谢!
回答:
AFAIK Spring标准事务管理不适用于WebFlux。
使用@Transactional
不会起作用,因为在调用带注释的方法时,事务机制会将事务状态保存ThreadLocal
在调用线程的内部。如您自己所说,这是行不通的。它阻止并共享状态。
但是,您可以使用a
.runOn(Schedulers.parallel())
命令将阻止代码发送到另一个线程。这样,您可以拥有一个带有可阻塞线程的线程池,您可以将其配置为与数据库连接池相同的大小。
但是即使如此,您还是不能依靠它,@Transactional
因为胎面池重用了线程。在标准Servlet体系结构中,每个HTTP请求只有一个线程。返回响应后,线程将停止,这将关闭事务。但是在这种情况下,Reactor调度程序不会关闭线程,而是将其重用于其他事件。因此,即使您可以阻止,您仍然会遇到与以前相同的问题。
您确实有Context
提到的选项,我认为这对您有用Mono
。我不确定它是否适用Flux
(我认为Flux中的所有事件都共享相同的上下文,这是您不想要的)。
另一个选择是使用Touple2 T1
作为业务对象和T2
事务上下文。我不建议这样做,因为您将业务逻辑与技术内容混合在一起,并且使事情变得过于复杂。
我最好的选择是亲自进行事务/连接管理:
- 获取数据库连接
- 开启TX
- 做阻塞IO的东西
- 关闭TX
- 关闭/释放数据库连接
都在阻塞线程上的一个代码块中。
这样会更安全(无泄漏)并且更易于理解。另外,由于您基本上可以自己做所有事情,因此您可以选择最适合您的情况的错误处理方式。
以上是 Spring事务管理可以与Spring WebFlux一起使用吗? 的全部内容, 来源链接: utcz.com/qa/432431.html