私はGuava EventBusを同期して使用しています。いずれかのサブスクライバがExceptionをスローすると、どのようにトランザクション全体をロールバックできますか? EventBus加入者が捕捉しないExceptionをどのように投げることができますか?Guava EventBusサブスクライバから例外をスローする
答えて
私は、出版社とサブスクライバ間で変数java.lang.ThreadLocal
を使用して解決しました。
Publisherは、ローカル例外をスレッド読み込み、
public void publish(Event event) {
eventBus.post(event);
if(threadLocalException != null) {
Store threadLocalException in some variable say e
Clear threadLocalException variable
throw e;
}
}
加入者は、スレッドローカル変数
public abstract class EventSubscriber<T extends Event> {
@Subscribe
public void invoke(T event) {
try {
handle(event);
} catch (Exception e) {
Set thread local variable to e
}
}
protected abstract void handle(T event);
}
GuavaのEventBus
クラスのソースコードを見るだけでいいです。
端から始めるのをしてみましょう:
にはどうすればEventBus加入者によってキャッチされることはありません例外を投げることができますか?
com.google.common.eventbus.Dispatcher#dispatch
メソッドによって、加入者のメソッドが次々に呼び出されます。あなたのサブスクライバのメソッドを呼び出すために、EventBusはリフレクションのメソッドMethod#invoke
を使用し、呼び出されたメソッドが例外をスローするとInvocationTargetException
をスローします。
次のように扱われますが、また、(あなたのException
に巻き付けされる)InvocationTargetException
、見ることができるように:
} 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
例外ハンドラを省略する唯一の方法Exception
ではなく、Error
をあなたの購読方法で投げることです。これは確かに悪い習慣です。
サブスクライバのいずれかが例外をスローすると、完全なトランザクションをどのようにロールバックできますか?
EventBus
例外ハンドラは、com.google.common.eventbus.EventBus#handleSubscriberException
メソッドを呼び出すことによって例外を処理します。
try {
exceptionHandler.handleException(e, context);
} catch (Throwable e2) {
// logging
}
例外ハンドラからスローされた例外は役に立ちません。
- どちらのスローエラー:あなたは2つの選択肢があります。私はそのようなもののための最良の場所は明らかに
EventBus
例外ハンドラだと思う。
EventBusを継承し、例外をスローする独自のeventBusを作成します。 パッケージはcom.google.common.eventbusでなければなりません。handleSubscriberExceptionは内部メソッドです。
package com.google.common.eventbus;
import com.google.common.util.concurrent.MoreExecutors;
/**
* A eventbus wihch will throw exceptions during event handle process.
* @author ytm
*
*/
public class ErrorThrowEventBus extends EventBus {
/**
* Creates a new EventBus with the given {@code identifier}.
*
* @param identifier a brief name for this bus, for logging purposes. Should be a valid Java
* identifier.
*/
public ErrorThrowEventBus(String identifier) {
super(
identifier,
MoreExecutors.directExecutor(),
Dispatcher.perThreadDispatchQueue(),
LoggingHandler.INSTANCE);
}
/**
* Creates a new EventBus with the given {@link SubscriberExceptionHandler}.
*
* @param exceptionHandler Handler for subscriber exceptions.
* @since 16.0
*/
public ErrorThrowEventBus(SubscriberExceptionHandler exceptionHandler) {
super(
"default",
MoreExecutors.directExecutor(),
Dispatcher.perThreadDispatchQueue(),
exceptionHandler);
}
/**
* Just throw a EventHandleException if there's any exception.
* @param e
* @param context
* @throws EventHandleException
*/
@Override
void handleSubscriberException(Throwable e, SubscriberExceptionContext context) throws EventHandleException {
throw new EventHandleException(e);
}
}
- 1. Google Guavaで例外を起動するEventBus
- 2. Guava CacheLoaderがカスタム例外をスロー&キャッチ
- 3. Guava EventBusユニットテスト
- 4. 例外から例外をスローする
- 5. Guava EventBusで別のスレッドからイベントをポストする
- 6. Guava java EventBusのインスタンス化エラー
- 7. Guava EventBus:イベントハンドラから結果を返す方法
- 8. カスタムクラスライブラリから例外をスローする
- 9. Process.Exitedハンドラから例外をスローする
- 10. WebGLから例外をスローする
- 11. シングルトンイニシャライザから例外をスローする
- 12. =例外をスローする例外
- 13. SnackBar BackgroundColor EventBus例外の変更
- 14. openFileOutput例外をスローする
- 15. OutOfMemoryError例外をスローする
- 16. RESTHEART例外をスローする
- 17. UseHangfireServer例外をスローする
- 18. コンテンツプロバイダ例外をスローする
- 19. バブルソート例外をスローする
- 20. Mockito例外をスローする
- 21. カスタム例外をスローする
- 22. 例外をスローする
- 23. spring boot guava eventbus listenerの登録を解除するには?
- 24. parseObject.saveInBackground()スロー例外
- 25. スロー例外
- 26. eglGetDisplay()スロー例外
- 27. アンドロイドネイティブコードからC++例外をスローするとスレッドがハングする
- 28. グアバでコンパイルするとgwt 2.8例外がスローされる20
- 29. Linux上のJerseyからJsonを返す例外をスローする
- 30. GuavaのEventBusのように動作するメッセージングサービス
Iに例外を設定するには、クラスにラップする必要があり、それをスローするクラスにラップする必要がありますこれらのいずれかが可能であれば、驚くべきことです。 –
これらが不可能な場合、これはイベントバスの制限ではありませんが、トランザクションでは使用できません。 – Shikhar
はい。もちろん。 –