quarkus:IllegalStateException:您试图在IO线程上执行阻止操作。不允许这样做,因为这会阻塞IO线程

我对夸克有一件事难以理解。 我将JPA与Oracle一起使用。所以我有错误 IllegalStateException:您试图在IO线程上执行阻止操作。不允许这样做,因为阻塞了IO线程 我在Quarkus文档中研究了如何进行JPA调用而又没有这个困难。但是所有示例和文档都使用带有响应客户端的PostgreSQL或MariaDB。但是我还没有找到任何经典的JDBC客户端。

我找到了一个部分起作用的解决方案。

Uni.cretaFrom().Items(() -> MyBlokingIOCall());

事实上,我不再例外。 但是MyBlokingIOCall方法可以引发异常。 我想我可以使用Uni的onFailure,但是我们不能通过引发异常的方法来

Uni.cretaFrom().Items

实际上,此方法有一个供应商作为参数,因此必须捕获异常。 此解决方案无法使用Uni的onFailure。 如果我在命令模式下使用当前代码

try {
   Response.ok (myService ());
} catch (throwable e) {
   Response.status (555,e.getMessage ());
}

我徒劳地尝试以反应形式进行此操作 但我没有找到解决方案。我没有找到任何帮助。 我想像类似的东西。

Uni.createFrom().Items(() -> myService())
.onItem().apply(data -> Response.ok(data))
.onFailure().apply(err -> Response.status(555,err.getMessage()))

但这会导致编译错误。确实是方法 myService不能在供应商中使用,因为它会引发异常。因此必须将其捕获。但是后来我们不再进入Uni的onFailure,也无法跟踪发现的错误。

我认为我对使用命令式代码而不是换个思路思考得太多了。

但是我找不到任何形式的文档或示例。我想有一种做事的方法(如果没有Quarkus的话就不会存在)。我认为,如果使用正确的方法进行考虑,就必须找到文档,但是当您不知道要去哪里时,它会变得更加复杂。我没有找到它,因为我不知道自己在寻找什么。

我想我必须封装产生一个Uni或Multi的JPA调用,该调用被处理器消耗,该处理器将Entity转换为DTO,然后将其传输到资源Rest层,该资源Rest层将DTO转换为Response。 JPA调用也必须能够在处理器和资源层上产生错误

因此,有必要在每个步骤中捕获这些错误,以通过Uni或Multi传播它们。

但是怎么做?

orgjava 回答:quarkus:IllegalStateException:您试图在IO线程上执行阻止操作。不允许这样做,因为这会阻塞IO线程

通过简单地提供 lambda 实现(或方法引用)作为方法调用参数,这在简洁性和最初期望方面是一种已知的 lambda 限制

与此同时,可以通过围绕预期的功能接口实施扩展来简单地解决此问题,在您的情况下,它将是Supplier<T>,它将捕获任何被选中的*** *例外,并抛出未经检查的一个:

/**
 * A Supplier sub-interface that catches any thrown exception
 * and translates to an unchecked one.
 *
 * <p>This is a functional interface whose functional method is
 * {@link #getChecked()}.
 */
@FunctionalInterface
public interface CheckedSupplier<T> extends Supplier<T> {

    @Override
    default T get() {
        try {
            return getChecked();
        } catch (final Exception e) {
            // Your common exception handling logic here..
            throw new RuntimeException(e);
        }
    }

    /**
     * Gets a result.
     *
     * @return a result
     * @throws Exception
     */
    T getChecked() throws Exception;
}

请注意,功能界面签名不再是 #get(),而是 #getChecked()。但这对编译器没有什么影响,编译器将尝试根据期望的签名检查功能签名,即:

返回T型对象的方法

然后,您只需在需要CheckedSupplier(或类似)的任何地方使用显式的 cast 即可使用新的Supplier<T>界面:

Uni.createFrom().item((CheckedSupplier<DataType>) MutinyTest::findOne)
      .onItem()
      .apply(i-> Response.ok(i))
      .onFailure()
      .apply(e-> Response.status(555,e.getMessage()));
,

我更改了myService方法,以使其返回供应商 并处理异常

   public Supplier<List<String>> myService (String arg){
      return () -> {
         try {
            //my code
            return result;
         } catch (Exception e) {
            throw new RuntimeException(e);
         }
      };
   }

我叫它

Uni.createFrom().item(myService("sample")))
.onItem().apply(data -> Response.ok(data))
.onFailure().recoverWithItem(err -> Response.status(600,err.getMessage()))
.onItem().apply(ResponseBuilder::build)
.emitOn(Infrastructure.getDefaultExecutor())
本文链接:https://www.f2er.com/2303373.html

大家都在问