3

根据我的理解,我想遵循最后释放资源的最佳实践,以防止任何连接泄漏。这是我在 HelperClass 中的代码。

public static DynamoDB getDynamoDBConnection()
{   
    try
    {
        dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
    }
    catch(AmazonServiceException ase)
    {
        //ase.printStackTrace();
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);
    }
    catch (Exception e)
    {
        slf4jLogger.error(e);
        slf4jLogger.error(e.getStackTrace());
        slf4jLogger.error(e.getMessage());
    }
    finally
    {
        dynamoDB.shutdown();
    }
    return dynamoDB;
}

我的疑问是,由于finally块无论如何都会被执行,dynamoDB是否会返回空连接,因为它将在finally块中关闭然后执行return语句?TIA。

4

4 回答 4

9

你的理解是正确的。dynamoBD.shutdown()将始终在之前执行return dynamoDB

我不熟悉您正在使用的框架,但我可能会按如下方式组织代码:

public static DynamoDB getDynamoDBConnection()
        throws ApplicationSpecificException {   
    try {
        return new DynamoDB(new AmazonDynamoDBClient(
                                    new ProfileCredentialsProvider()));
    } catch(AmazonServiceException ase) {
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);
        throw new ApplicationSpecificException("some good message", ase);
    }
}

并将其用作

DynamoDB con = null;
try {
    con = getDynamoDBConnection();
    // Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
    // deal with it gracefully
} finally {
    if (con != null)
        con.shutdown();
}

您还可以为您的 dynamoDB 连接(在内部AutoCloseable调用)创建一个包装器并执行shutdownclose

try (DynamoDB con = getDynamoDBConnection()) {
    // Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
    // deal with it gracefully
}
于 2015-06-19T11:09:14.803 回答
1

是的,dynamoDB 将返回一个空连接,这dynamoBD.shutdow()将在 return 语句之前执行,Always。

于 2015-06-19T11:10:39.243 回答
1

尽管我没有回答您关于始终执行 finally 块的问题(该问题已经有几个答案),但我想分享一些有关如何使用 DynamoDB 客户端的信息。

DynamoDB 客户端是一个线程安全对象,旨在在多个线程之间共享 - 您可以为您的应用程序创建一个全局对象,并在需要时重新使用该对象。通常,客户端创建由某种 IoC 容器(例如 Spring IoC 容器)管理,然后由容器通过依赖注入提供给任何需要它的代码。

在底层,DynamoDB 客户端维护一个 HTTP 连接池,用于与 DynamoDB 终端节点进行通信,并使用该池中的连接。在构建客户端时,可以通过传递一个ClientConfiguration对象的实例来配置池的各种参数。例如,参数之一是允许打开的 HTTP 连接的最大数量。

有了上面的理解,我想说由于 DynamoDB 客户端管理 HTTP 连接的生命周期,资源泄漏不应该真正成为使用 DynamoDB 客户端的代码的关注点。

于 2015-06-19T19:28:37.080 回答
0

我们如何“模仿”错误并看看会发生什么?这就是我的意思:

___情况1___

try{
  // dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
  throw new AmazonServiceException("Whatever parameters required to instantiate this exception");
}    catch(AmazonServiceException ase)
    {
        //ase.printStackTrace();
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);

    }
    catch (Exception e)
    {
        slf4jLogger.error(e);
        slf4jLogger.error(e.getStackTrace());
        slf4jLogger.error(e.getMessage());
    }
    finally
    {
        //dynamoDB.shutdown();
        slf4jLogger.info("Database gracefully shutdowned");
    }

___案例2___

try{
  // dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
  throw new Exception("Whatever parameters required to instantiate this exception");
}    catch(AmazonServiceException ase)
    {
        //ase.printStackTrace();
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);

    }
    catch (Exception e)
    {
        slf4jLogger.error(e);
        slf4jLogger.error(e.getStackTrace());
        slf4jLogger.error(e.getMessage());
    }
    finally
    {
        //dynamoDB.shutdown();
        slf4jLogger.info("Database gracefully shutdowned");
    }

这些练习可能是使用单元测试,更具体地说是模拟测试的理想场所。我建议您仔细查看JMockit,它将帮助您更轻松地编写此类测试。

于 2015-06-19T11:18:54.353 回答