spring-integration - 使用 TransactionInterceptor 抛出 java.lang.IllegalStateException:无法将反应式事务应用于非反应式返回类型:void
问题描述
我的代码是:
@Bean(R2DBC_TRANSACTION_INTERCEPTOR)
public TransactionInterceptor R2DBCTransactionInterceptor(ReactiveTransactionManager reactiveTransactionManager) {
return new TransactionInterceptorBuilder(true)
.transactionManager(reactiveTransactionManager)
.isolation(Isolation.READ_COMMITTED)
.propagation(Propagation.REQUIRES_NEW)
.build();
}
@ServiceActivator(inputChannel = "create invoice",
adviceChain = {IntegrationConfiguration.R2DBC_TRANSACTION_INTERCEPTOR})
public Mono<Invoice> createInvoice(Invoice invoice) {
return invoiceRepository.save(invoice);
}
我得到了一个异常 java.lang.IllegalStateException: Cannot apply reactive transaction to non-reactive return type: void at org.springframework.transaction.interceptor.TransactionAspectSupport.lambda$invokeWithinTransaction$0(TransactionAspectSupport.java:348) ~[spring-tx- 5.2.8.RELEASE.jar:5.2.8.RELEASE]
即使在消息传递过程中没有异常,createInvoice 方法也会以该异常调用。
有针对这种情况提供的演示吗?我的配置错了吗?
解决方案
new TransactionInterceptorBuilder(true)
查看它的 JavaDocs:
* When the {@code handleMessageAdvice} option is in use, this builder produces
* {@link TransactionHandleMessageAdvice} instance.
然后我们去提到的TransactionHandleMessageAdvice
:
* When this {@link org.aopalliance.aop.Advice}
* is used from the {@code request-handler-advice-chain}, it is applied
* to the {@link org.springframework.messaging.MessageHandler#handleMessage}
* (not to the
* {@link org.springframework.integration.handler.AbstractReplyProducingMessageHandler.RequestHandler#handleRequestMessage}),
* therefore the entire downstream process is wrapped to the transaction.
现在,如果我们看一下MessageHandler#handleMessage
,我们会看到:
void handleMessage(Message<?> message) throws MessagingException;
因此,这就是该事务拦截器被注入的地方,这就是您的解决方案由于void
来自handleMessage()
.
你真的需要考虑你是否确实需要一个事务(尤其是反应性的)来处理整个子流程@ServiceActivator
......
我的意思是你可能只是new TransactionInterceptorBuilder()
可以让你的@ServiceActivator
事务处理并且已经使用那个反应式 TX 管理器,因为你确实返回了一个Mono
.
推荐阅读
- c++ - __cdecl 调用约定在 msvc x64 上不起作用
- python - Scipy fsolve:使用序列设置数组元素
- google-chrome - 使用 Google API 的 Chrome 扩展中的 PUT 请求未呈现
- c# - 将列表中的项目复制到具有固定大小的数组
- json - 在 Swift 中解析 JsonString
- javascript - Angular:如何覆盖来自不同模块的共享模块服务
- python - 如何在 initializable_iterator 上使用 shared_name
- pentaho - 在 pentaho 报告 5.4 版本中垂直旋转文本
- html - 如何在网页中显示 .ipynb 文件的输出?
- c++ - 使库函数模板化以避免编译器指令是否有益?