web-dev-qa-db-ja.com

C3P0を使用したJDBC接続プーリング

以下は、DB接続を取得するための私のヘルパークラスです。

here の説明に従って、C3P0接続プーリングを使用しました。

public class DBConnection {

    private static DataSource dataSource;
    private static final String DRIVER_NAME;
    private static final String URL;
    private static final String UNAME;
    private static final String PWD;

    static {

        final ResourceBundle config = ResourceBundle
                .getBundle("props.database");
        DRIVER_NAME = config.getString("driverName");
        URL = config.getString("url");
        UNAME = config.getString("uname");
        PWD = config.getString("pwd");

        dataSource = setupDataSource();
    }

    public static Connection getOracleConnection() throws SQLException {
        return dataSource.getConnection();
    }

    private static DataSource setupDataSource() {
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        try {
            cpds.setDriverClass(DRIVER_NAME);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        cpds.setJdbcUrl(URL);
        cpds.setUser(UNAME);
        cpds.setPassword(PWD);
        cpds.setMinPoolSize(5);
        cpds.setAcquireIncrement(5);
        cpds.setMaxPoolSize(20);
        return cpds;
    }
}

dAOでは、次のように記述します。

try {
            conn = DBConnection.getOracleConnection();

            ....


} finally {
    try {
        if (rs != null) {
            rs.close();
        }
        if (ps != null) {
            ps.close();
        }
        if (conn != null) {
            conn.close();
        }
    } catch (SQLException e) {
        logger
                .logError("Exception occured while closing cursors!", e);

    }

さて、私の質問は、finallyブロックにリストされているカーソル(connection/statement/resultSet/preparedStatement)を閉じる以外に、他のクリーンアップを行う必要があるかどうかです。

this cleanupとは何ですか??いつどこでこれを行うべきですか?

上記のコードに誤りがある場合は、指摘してください。

29
jai

プールされたデータソースでは、プール内の接続は実際には閉じられず、プールに戻されるだけです。ただし、アプリケーションがシャットダウンされると、データベースへのこれらの接続は適切に、実際に閉じられるはずです。ここで最終的なクリーンアップが行われます。

ちなみに、c3p0プロジェクトは水中でほとんど死んでいます。代わりに Apache Commons DBCP を使用することをお勧めします。それはまだ維持されています。

23
skaffman

DAOは、データベースへの接続を取得する責任を負いません。大規模なトランザクションの一部としていつ使用されているかを知る方法はありません。データソースまたは接続インスタンスをDAOに渡す必要があります。

Finallyブロックで閉じるための呼び出しのいずれかが例外をスローする場合、後続の呼び出しは呼び出されません。それぞれが独自のtry/catchブロックにある必要があります。それらを静的メソッドとしてユーティリティクラスに入れました。

6
duffymo

私にはコードは問題なく見えますが、クローズ操作を行うヘルパーメソッドを記述するか、すべてのDAOまたはメソッドでこの冗長な最終ブロックを取得します。おそらく、ステートメントと結果セットが実行をスローしたかどうかに関係なく接続が閉じられることを確認するために、クローズ操作の周りに3つの別々のtry-catch-blocksを書く必要があります。また、 javadoc says

Statementオブジェクトが閉じられると、現在のResultSetオブジェクト(存在する場合)も閉じられます。

したがって、上記の例で結果セットを閉じる必要はありませんが、できます。

リンクされたクリーンアップメソッドは、データソースを閉じるためのもので、アプリが実行されている限りDSが存続するため、ほとんどのプロジェクトでは必要ありません。

5
Tim Büthe

私はPlay FrameworkとScalaを使用しているため、次の例はplayプロジェクトにあります。

ステップ1。構成

Build.sbtで、データベースとしてmysql/Hiveを使用する場合、これらのプロパティを追加する必要があります。

libraryDependencies ++ = Seq (
   jdbc,
  "mysql" % "mysql-connector-Java" % "5.1.31",
  "org.Apache.Hive" % "Hive-jdbc" % "0.12.0",
  "com.mchange" % "c3p0" % "0.9.2.1"
)

ステップ2。アクセスする方法は? c3p0ライブラリをインポートする必要があります。

import com.mchange.v2.c3p0.ComboPooledDataSource

ステップ3。次に、インスタンスを作成する必要があります。

val cpds = new ComboPooledDataSource()
cpds.setDriverClass(...)
cpds.setJdbcUrl(...)
cpds.setUser(...)
cpds.setPassword(...)

ステップ4。接続を取得します

cpds.getConnection
0
Haimei