java - 从 Guava EventBus 订阅者抛出异常

标签 java jpa guava event-bus

我正在同步使用 Guava EventBus。如果任何订阅者抛出异常,我如何回滚整个事务?如何抛出一个不会被 EventBus 订阅者捕获的异常?

最佳答案

您所要做的就是查看 Guava 的 EventBus 类的源代码。

让我们从最后开始:

How can I throw an Exception which will not be caught by the EventBus Subscriber?

订阅者的方法由 com.google.common.eventbus.Dispatcher#dispatch 方法依次调用。为了调用订阅者的方法,EventBus 使用反射的方法 Method#invoke,如果被调用的方法抛出异常,该方法会抛出 InvokingTargetException

正如您所看到的,InitationTargetException(它将包裹在您的Exception周围)的处理如下:

} catch (InvocationTargetException e) {
  if (e.getCause() instanceof Error) {
    throw (Error) e.getCause();
  }
  throw e;
}

在上层,异常的处理方式如下:

try {
  invokeSubscriberMethod(event);
} catch (InvocationTargetException e) {
  bus.handleSubscriberException(e.getCause(), context(event));
}

TL;DR

因此,省略 EventBus 异常处理程序的唯一方法是在订阅方法中抛出 Error,而不是 Exception - 当然是这样不好的做法。

How can I rollback the complete transaction if any of the subscribers throw an Exception?

EventBus 异常处理程序通过调用 com.google.common.eventbus.EventBus#handleSubscriberException 方法来处理异常。它看起来像这样:

try {
  exceptionHandler.handleException(e, context);
} catch (Throwable e2) {
  // logging
}

因此,从异常处理程序抛出的任何异常都无济于事。您有两个选择:

  1. 要么从订阅者方法中抛出错误(这太糟糕了)
  2. 或者从该流程中的任何位置手动将事务设置为仅回滚。我认为处理此类事情的最佳位置显然是 EventBus 异常处理程序。

关于java - 从 Guava EventBus 订阅者抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37974801/

相关文章:

java - 如何通过 TestNG 参数化配置环境 URL?

java - Spring ACL 是一个好的 ACL 实现吗?

java - 是否 hibernate 分离对象的默认乐观锁定?

java - 用汉字声明字符串

java - Hibernate:通过示例和多对一关系进行查询

java - Spring中entityManager上的NullPointerException

caching - 当 load 执行时调用 invalidate 时,google Guava LoadingCache 会做什么?

java - 具有 Inheritance.JOINED 的 Spring Data Repository

java - Guava CacheLoader 未命中

java - Java 客户端尝试连接到 Elastic Search 时出错