如何从cassandra executeAsync()方法抛出异常调用方法

时间:2017-09-18 12:53:52

标签: java multithreading cassandra threadpoolexecutor

我有一种情况,当一些cassandra查询可能失败,我想重新抛出异常回到调用方法,我需要根据发生的异常执行一些任务,我无法实现它可能接近可用的像注册uncaughtExceptionHandler机制或通过向cassandra驱动程序的executeAsync()方法返回的Future对象添加回调处理程序。请帮帮我。

ThreadPoolExcecutor.java -

class ThreadPoolExecutor {

private static ThreadPoolExecutor instance;
ExecutorService executor;

public static synchronized ThreadPoolExecutor getInstance()
{
    if( instance == null )
    {
        instance = new ThreadPoolExecutor();
    }
    return instance;
}

private ThreadPoolExecutor()
{
    executor = Executors.newFixedThreadPool(16);
}

}

我的Runnable类 -

class CassanndraExecCommand implements Runnable {

private final Session session;
private final Statement statement;

public CassanndraExecCommand( Session session, Statement statement )
{
    this.session = session;
    this.statement = statement;
}

@Override
public void run()
{
    ResultSetFuture future = session.executeAsync(statement);
    Futures.addCallback(future, new FutureCallback<ResultSet>() {

        @Override
        public void onSuccess( ResultSet result )
        {
            // do nothing";
        }

        @Override
        public void onFailure( Throwable t )
        {
            throw new RuntimeException(t);
        }
    });
}

}

正如您在上面所看到的,我在失败的情况下重新抛出异常。现在的问题是如何在我的调用方法中捕获此异常,如下所示 -

public static void executeSaveorUpdate( Statement statement, String keyspaceName )
{
    ThreadPoolExecutor.getInstance().executor
            .execute(new CassanndraExecCommand(getSession(keyspaceName), statement));
}

注意 - 我正在使用的cassandra版本是2.2.6

2 个答案:

答案 0 :(得分:1)

您无法捕获已在其他线程中抛出的异常 所以,你所能做的就是使用回调来处理异常 这是我们为异步非阻塞呼叫性能付出的代价。

顺便说一句,如果你只需要回调失败,你可以省略“onSuccess”:

Futures.addCallback(future,
    new MoreFutures.FailureCallback<T>() {
        @Override
        public void onFailure(Throwable t) {
        //Do whatever you need with t
        }
    },
    executor);

答案 1 :(得分:0)

我建议使用ExecutorService.submit(Runnable)方法代替execute。提交将为您返回Future<T>对象,因此您可以轻松处理异常(如果有)。

Future<Void> result = ThreadPoolExecutor.getInstance().executor
        .submit(new CassanndraExecCommand(getSession(keyspaceName), statement));
try {
    result.get();
} (catch ExecutionException e) {
    // e.getCause() will return your root exception
}

希望它有所帮助!

除此之外,我认为用Callable实施Runnable代替CassanndraExecCommand会更好。这允许您完全处理Cassandra响应(包括好的和坏的)并避免回调。