アプリ版:「スタンプのみでお礼する」機能のリリースについて

BasicDataSourceについて

ドキュメントを見ると
closeメソッドがあるのですが
DataSource使用後
DataSource自体をclose
する必要があるのでしょうか?
このDataSourceにより生成された
Connectionをクローズすれば問題無いでしょうか?

感覚だとDataSourceなんて
接続先情報(文字列情報)として認識しているので
それをcloseするのが良くわかりません。


ドキュメント
http://commons.apache.org/dbcp/apidocs/org/apach …

A 回答 (2件)

さて困ったわね。


あなたがどの程度理解しているのか
このAPIを使ってどのような使い方をしているのかもわからないし。
でも、とりあえず言うだけ言ってみるわ。

---------
データベースコネクションをプーリングするようにしていた場合、
BasicDataSourceのgetConnectionで
コネクションプールから1つ借りることができるわ。
そのConnectionをcloseをすることで
借りたコネクションをコネクションプールの中に返すことができるの。

JavaVMがコネクションプールを管理しているはず
そのVMの開始時に恐らくコネクションプールを作るようになっていると思うので
VM終了時にBasicDataSourceのcloseをしてあげると良いわ。
それ以外のときにBasicDataSourceをcloseする必要ないわ。

コネクションプーリングを使っていない場合も
まったく同じ実装で良いわ。
違うのは
BasicDataSourceのgetConnectionで
データベースへのコネクションを作成し
そのConnectionをcloseをすることで
データベースから切断するってことね。
---------

とりあえずこの説明でどうかしら。

この回答への補足

回答ありがとうございます。
ご説明わかりやすいですが。
認識違いしているといけないので
もう一度お願いします。

ConnectionやDataSourceを扱うコードでバグでも
出した日にはと思うと不安で仕方ないのです。

次のような簡単なコードがあるとします。
DataSourceFactoryはDataSource生成管理オブジェクト
関数hogeはそのDataSourceFactoryを利用する関数です。
また、例外発生でclose漏れが起きる話は除きます。
------
public void hoge () throws SQLException {
  final DataSourceFactory factory = new DataSourceFactory();
  final DataSource dsA = factory.getDataSource("A");
  final Connection conA = dsA.getConnection();
  /* conAでDB接続 */
  conA.close();//【1】
  final DataSource dsB = factory.getDataSource("A");
  final Connection conB = dsA.getConnection();
  /* conBでDB接続 */
  conB.close();//【2】
  factory.close();//【3】
}

public class DataSourceFactory {
  private final Map dataSourcePool = new HashMap();
  //SingletonなDataSource FlyweightFactory(hoge#【1】【2】から呼ばれる処理)
  public DataSource getDataSource (final String key) {
    final Map pool = this.dataSourcePool;
    DataSource retval = null;
    if (pool.containsKey(key)) {
      retval = pool.get(key);
    } else {
      final BasicDataSource ds = new BasicDataSource();
      /* dsに接続先情報などをセットする */
      retval = pool.put(key, ds);
    }
    return retval;
  }
  //生成された全てのDataSourceをclose(hoge#【3】から呼ばれる処理)
  public void close () throws SQLException {
    final Map pool = this.dataSourcePool;
    final List keyList = new ArrayList(pool.keySet());
    for (int i = 0; i < keyList.size(); i++) {
      ((BasicDataSource)pool.get(keyList.get(i))).close();
    }
  }
}
------
【1】と【2】のcloseが確実に出来れば
DataSourceFactory#close(【3】の処理)を呼ぶ必要はないですか?

逆に【3】を確実に呼べて、Connectionの返却時間が遅くなっても
構わないような処理であれば【1】【2】のcloseをする必要がない?

例をわかって頂ける様ささっとコード書いてみましたので
もしかしたら誤字等あったら申し訳ありません。
インデントは全角でつけてあります。
長文すみません。
宜しくお願いします。

補足日時:2010/09/21 23:55
    • good
    • 0

一般的にはそのアプリを終了するときにcloseするのよ。



closeすると何が起きるかはきちんとAPIドキュメントに書かれているんだから
その目的に合うときにcloseすればいいのよ。

この回答への補足

返信おそくなりましたが
回答ありがとうございます。

英語がわからないながらAPIをみました。
このDataSourceから生成されたConnectionを
直接closeすれば
org.apache.commons.dbcp.BasicDataSource#close
はしなくても良いと考えましたがあっていますでしょうか?

補足日時:2010/09/20 23:57
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!