3

ローカルSQLデータベースを使用してデータを格納するプログラムを作成しています。

ここにあるドライバーを使用しています:https ://bitbucket.org/xerial/sqlite-jdbc

データベースから読み取り、tableNameの内容を次のようにJTableに入れようとしています。

public Object[][] getTable(String tableName){
    int columns = getColumnNumber(tableName);
    int rows = getRowNumber(tableName);
    String[] columnNames = getColumnNames(tableName);
    Object[][] table = new Object[rows][columns];
    try{
        Connection connection = DriverManager.getConnection("jdbc:sqlite:" + dbName + ".db");
        Statement stmt = connection.createStatement();
        ResultSet rs = stmt.executeQuery("select * from " + tableName);
        for(int r = 0; r < rows; r++){
            rs.next();
            for (int c = 0; c < columns; c++){
                table[r][c] = rs.getString(columnNames[c]);
            }
        }
        return table;           
    }catch(Exception e){
        System.out.println("ERROR CREATING TABLE ARRAY");
        e.printStackTrace();
        return null;
    }
}

その後、戻ってテーブルに行を追加しようとします。

public boolean addRow(String tableName, Object[] values){
    if(!isDataAcceptable(tableName, values))
        return false;
    try{
        String stmt = "insert into " + tableName + " values (";
        for(int c = 0; c < values.length; c++){
            if(values[c] instanceof String)
                stmt += "'" + values[c] + "'";
            else
                stmt += values[c];
            if(c == (values.length - 1))
                    stmt += ");";
            else
                stmt += ", ";
        }
        System.out.println(stmt);
        Connection connection = DriverManager.getConnection("jdbc:sqlite:" + dbName + ".db");
        Statement statement = connection.createStatement();
        statement.executeUpdate(stmt);
        return true;
    }catch(Exception e){
        System.out.println("ERROR INSERTING ROW");
        e.printStackTrace();
        return false;
    }
}

次に、前に作成したJTableを新しい行で更新します。

ただし、行を追加しようとすると、例外が発生します。

java.sql.SQLException: database is locked

それは線を指しています:

statement.executeUpdate(stmt);

... addRow()メソッド内。

データベースがロックされているのはなぜですか。また、データベースに書き込むためにデータベースのロックを解除するにはどうすればよいですか。

4

1 に答える 1

4

データベースがロックされているのはなぜですか。また、データベースに書き込むためにデータベースのロックを解除するにはどうすればよいですか。

addRowの前の呼び出しgetTableで結果セットが閉じられなかったため、データベースがロックインされている可能性があります。また、コードはデータベース接続オブジェクトを閉じることができず、リソースリークが発生します。

基本的な修正はandオブジェクトを呼び出すclose()ことrsですconnectionが、コードを信頼できるものにするために正しい方法で呼び出す必要があります。

「リソースで試す」構文を使用してJava7でこれを行うための推奨される方法は次のとおりです。

try (Connection connection = 
         DriverManager.getConnection("jdbc:sqlite:" + dbName + ".db"),
     Statement stmt = connection.createStatement(),
     ResultSet rs = stmt.executeQuery("select * from " + tableName)) {
  for (int r = 0; r < rows; r++) {
    rs.next();
    for (int c = 0; c < columns; c++) {
      table[r][c] = rs.getString(columnNames[c]);
    }
  }
  return table;           
} catch (Exception e) {
    System.out.println("ERROR CREATING TABLE ARRAY");
    e.printStackTrace();
    return null;
}

closeブロック内で明示的に呼び出すことによってこれを行うこともできますがfinally、より冗長であり、閉じる必要のある関連リソースがある場合は、コードを正しく理解するのが難しい場合があります...ここのように。

于 2013-03-23T23:40:13.393 に答える