【问题标题】:Is there a good way to check whether a Datastax Session.executeAsync() has thrown an exception?有没有一种检查 Datastax Session.executeAsync() 是否引发异常的好方法?
【发布时间】:2014-04-14 21:00:09
【问题描述】:

我正在尝试通过调用session.executeAsync() 而不是session.execute() 来加快我们的代码写入速度。

我们有数据库连接可能断开的用例,当前之前的execute() 在连接丢失时抛出异常(集群中无法访问主机)。我们可以捕获这些异常并重试或将数据保存在其他地方等...

使用executeAsync(),看起来没有任何方法可以实现这个用例 - 需要访问返回的ResultSetFuture 对象以检查结果,这将违背使用executeAsync() 的目的第一名……

有没有办法在任何地方为 executeAsync() 调用添加一个监听器(或类似的东西),它会异步通知其他一些代码数据库写入失败?

这有关系吗? 数据税 1.0.2 Java 1.7.40

【问题讨论】:

    标签: java datastax datastax-java-driver


    【解决方案1】:

    您可以尝试这样的事情,因为 ResultSetFuture 实现了 Guava 库中的 ListenableFuture

        ResultSetFuture resultSetFuture = session.executeAsync("SELECT * FROM test.t;");
        Futures.addCallback(resultSetFuture, new FutureCallback<ResultSet>() {
            @Override
            public void onSuccess(@Nullable com.datastax.driver.core.ResultSet resultSet) {
                // do nothing
            }
    
            @Override
            public void onFailure(Throwable throwable) {
                System.out.printf("Failed with: %s\n", throwable);
            }
        });
    

    这种方法不会阻止您的应用程序。

    【讨论】:

    • 这看起来像是我正在尝试实施的解决方案 - 谢谢!
    【解决方案2】:

    您可以将回调传递给该方法以对异常采取措施。如果你需要ResultSetFuture,你可以试试这样的:

    interface ResultSetFutureHandler {
        void handle(ResultSetFuture rs);
    }
    
    public void catchException(ResultSetFutureHandler handler) {
        ResultSetFuture resultSet = null;
        try {
            resultSet = getSession().executeAsync(query);
            for (Row row : results.getUninterruptibly()) {
                // do something
            }
        } catch (RuntimeException e) {
            handler.handle(resultSet); // resultSet may or may not be null
        }
    }
    

    然后这样称呼它:

    catchException(new ResultSetFutureHandler() {
        void handle(ResultSetFuture resultSet) {
            // do something with the ResultSetFuture
        }
    });
    

    如果你想知道异常是什么,也添加一个异常参数:

    interface ResultSetFutureHandler {
        void handle(ResultSetFuture rs, RuntimeException e);
    }
    

    【讨论】:

    • 嗨!谢谢你的主意。但我认为 getUninterruptibly() 调用会阻塞,直到查询返回结果,所以这似乎会否定使用 executeAsync() 的好处?我正在研究如何使用 executeAsync() 来“即发即弃”查询,并以某种方式挂钩某种异步侦听器,如果出现异常,该侦听器将被调用。
    • 这就是它的作用。 “侦听器”是您传入的ResultSetFutureHandler - 当出现您想要的异常时,它会被调用。您可以将其以不同的方式捆绑在一起,使其更正式或更优雅,但想法是一样的。
    • 当您的代码示例中出现异常时,由于代码等待 getUninterruptibly() 调用,我们不是已经失去了 executeAsync() 的优势吗?这就是我看到示例操作的方式:` // executeAsync() 只抛出 IllegalStateException,我认为这并不表示网络故障 resultSet = getSession().executeAsync(query); // getUninterruptibly() 阻塞,直到查询实际运行并返回 // 从 javadoc:“等待查询返回并返回其结果。” for (Row row : resultSet.getUninterruptibly()) { `
    • cont'd 由于 getUniterruptibly() 会抛出寻找的 NoHostAvailableException/QueryExecutionException 但也会阻塞,直到查询运行,我认为调用该方法对我寻求异步处理没有帮助?
    • 我试图避免需要线程化任何东西,因为到那时我还不如线程化整个 DB 调用并简单地使用 execute() 而不是 executeAsync()。可能是我正在寻找的东西是不可能的:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    相关资源
    最近更新 更多