0

データベースへのアクセスを提供する単純な Java ライブラリを開発しています。現在、SQLite へのアクセスに取り組んでいます。インスタンスメソッドのみを実装する SQlite.java という名前のクラスがあります。以下は、いくつかのメソッドの実装です。

public ResultSet retrieve(String query) {
    try {
        if (this.connection != null) {
            this.statement = this.connection.createStatement();
            return this.statement.executeQuery(query);
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
    return null;
}

public ResultSet listTables() {
    try {
        return this.retrieve("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name");
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
    return null;
}

public boolean hasTable(String tableName) {
    try {
        ResultSet rs = this.listTables();
        while (rs.next()) {
            if (rs.getString(1).equals(tableName)) {
                return true;
            }
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
    return false;
}

public void update(String query) {
    try {
        if (this.connection != null) {
            this.statement = this.connection.createStatement();
            this.statement.executeUpdate(query);
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
}

public void dropTable(String tableName) {
    try {
        if (this.hasTable(tableName)) {
            this.update("DROP TABLE " + tableName); // TEST!
        } else {
            System.err.println("[ERROR] Table '" + tableName + "' not found!");
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
}

dropTable() メソッドをテストすると、「データベース テーブルがロックされています」という例外が発生します。これは、 hasTable() メソッドで呼び出される可能性のあるクローズされていない SELECT ステートメントが原因であると推測しています。私の知る限り、検索クエリが実行されてもデータベース テーブルはロックされているため、他のユーザーがデータを選択しようとしている間はテーブルを更新できません。しかし、これを解決する方法はわかりませんでした。何か案は?

4

1 に答える 1

1

あなたの環境が何であるかはわかりませんが、接続プールを備えたデータソースを使用し、トランザクションごとに接続を取得して閉じる必要があります。

完璧な方法は、コンテナー (Spring または Java EE のコンテナー) を使用してトランザクションを管理できるようにすることです。そのため、JDBC リソースを適切に管理する必要はありません。現在のトランザクションの更新を許可するかどうかを指定したり、分離などの追加のトランザクション プロパティを管理したりすることもできます。

どうしても jdbc を直接使用したい場合でも、ベスト プラクティスは、使用後に接続を閉じることです。あいまいな理由で読み取り接続を維持したい場合は、2 人の異なるユーザーを使用することをお勧めします。いずれの場合も、使用後に接続と最終的に準備されたステートメントを適切に解放するように注意する必要があります。そうしないと、デッドロックやメモリ リークが発生する可能性があります。

参照。http://javarevisited.blogspot.fr/2012/08/top-10-jdbc-best-practices-for-java.html

于 2013-03-04T17:04:25.823 に答える