3

アプリケーションで Dropwizard で JDBI を使用しています。dbi.open コマンドを使用して DAO インスタンスを取得し、それを使用してさまざまなクエリを実行しました。"finally" ブロックでは、dao.close() メソッドを使用して接続を閉じます。また、dao.inTransaction メソッドを使用して、1 つのトランザクションで複数の DB ステートメントを実行しました。

アプリケーションはしばらく問題なく動作していましたが、最近、Dev 環境と Prod 環境の両方で "PoolExhausted" 例外が数回見られました。dbi.onDemand を使用する方が dbi.open を使用するよりも優れたアプローチであり、最終的に毎回 close を呼び出す必要がなくなるかどうか疑問に思っています... dbi.open を使用すると、接続リークの背後にある理由になる可能性があります?

4

1 に答える 1

4

それは、接続のオープンとクローズの間に私たちが行っているすべてのことによって異なります。

public interface UserDao {
  @SqlQuery("select * from users")
  public List<User> getUsers();

  @SqlUpdate(some query..)
  public void insertUsers(someParam);

}

UserDao dao = dbi.onDemand(UserDao.class);
dao.getUsers();

UserDao dao = dbi.open(UserDao.class);
dao.getUsers();
dao.close();

ここでは、接続を取得することと接続を閉じることに違いはありません。

UserDao dao = dbi.onDemand(UserDao.class);
dao.getUsers();
// calling external service to get some value.
dao.insertUsers();

UserDao dao = dbi.open(UserDao.class);
dao.getUsers();
// calling external service to get some value.
dao.insertUsers();
dao.close();

この例では、onDemand メソッドで、getUsers 呼び出しの前に接続が開かれ、その後閉じられます。同じことがinsertUsersにも起こりました。外部サービス呼び出し中は接続を保持しません。

Dbi open メソッドでは、接続は getUsers の前に開かれ、insertUsers の後に閉じられます。外部サービス呼び出し中も接続を保留します。この外部呼び出しにコストがかかる場合、接続が長時間アイドル状態になり、他のユーザーに使用できなくなります。

そのため、onDemand を使用して Dao インスタンスを取得することをお勧めします。

于 2015-06-29T04:22:52.770 に答える