Spring Transaction Management是否适用于Spring WebFlux? [英] Does Spring Transaction Management Work with Spring WebFlux?

查看:1149
本文介绍了Spring Transaction Management是否适用于Spring WebFlux?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spring对RDBMS事务管理的支持是否也适用于Spring WebFlux?

Does Spring's support for RDBMS transaction management also work in Spring WebFlux?

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

For example, assuming proper configuration, will a method annotated with the @Transactional annotation use the Spring transaction manager and rollback the transaction if an error occurs?

如果事务管理确实有效,那么 @Transactional 方法实际上必须抛出和异常,或者必须 Mono Flux 返回类型发出错误信号?

If transaction management does work, must a @Transactional method actually throw and exception, or must the Mono or Flux return type emit an error signal?

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

I know JDBC is inherently blocking, and thus any JDBC operations must be bridged from blocking to reactive, or vice-versa.

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

The Spring transaction manager works by using a ThreadLocal (right?) which I'm assuming won't work in a Reactor environment, since Reactor is frugal with threads and a single thread can swap out one unit of work for another while the first is waiting on I/O. I know Reactor has the Context object which is conceptually similar to ThreadLocal (right?) but I haven't seen any documentation that mentions that transaction makes use of it. Additionally, all JDBC operations that occur within a transaction must use the same Connection which might be tough to do in a reactive context.

我的组织有WebFlux和Cassandra的经验,但Cassandra有本地反应驱动程序。

My organization has experience with WebFlux and Cassandra, but Cassandra has a native reactive driver.

谢谢!

推荐答案

AFAIK Spring标准事务管理不适用于WebFlux。

AFAIK the Spring standard transaction management does not work with WebFlux.

使用 @事务性将无法工作,因为当调用带注释的方法时,事务机制会将事务的状态保存在调用线程的 ThreadLocal 中。正如你自己说的那样,这不起作用。它阻止AND它共享状态。

Using the @Transactional will not work because when an annotated method is called, the transaction mechanism will save the state of the transaction inside the ThreadLocal of the calling thread. As you have said it yourself, this does not work. It blocks AND it shares state.

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

However, you can use a .runOn(Schedulers.parallel()) in order to send the blocking code to another thread. This way you can have a thread pool with blockable threads which you can configure to have the same size as you DB connection pool.

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

But even so you still cannot rely on @Transactional because of the way the tread pool reuses the threads. In a standard Servlet architecture you have one thread per HTTP request. When the response is sent back, the thread is stopped, which closes the transaction. In this case though, the Reactor scheduler does not close the threads and reuses them for other events. So even if you CAN block you still have the same problem as before.

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

You do have the Context option you've mentioned and I think this would work for Mono. I'm not sure if it would work for a Flux (I'm thinking that all events in a Flux share the same context, which is what you don't want).

另一个选择是使用带有 T1 的Touple2作为业务对象, T2 交易上下文。我不能推荐这个,因为你将业务逻辑与技术资料混合在一起并使事情过于复杂。

Another option is to use a Touple2 with T1 as the business object and T2 the transaction context. I cannot recommend this though since you mix business logic with technical stuff and it overcomplicates things.

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

My best bet would be to do the transaction/connection management yourself:


  1. 获取数据库连接

  2. 打开TX

  3. 阻止IO内容

  4. 关闭TX

  5. 关闭/释放数据库连接

  1. Get DB connection
  2. Open TX
  3. Do blocking IO stuff
  4. Close TX
  5. Close/release DB connection

阻塞线程中的所有代码块。

all in one code block on a blocking thread.

这将更安全(无泄漏)且更易于理解。另外,因为您基本上可以自己完成所有操作,所以您可以选择哪种错误处理最适合您的场景。

This will be safer (no leaks) and easier to understand. Also because you basically do everything yourself, you can chose what kind of error handling works best for your scenario.

这篇关于Spring Transaction Management是否适用于Spring WebFlux?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆