0

hsqldb を使用して、キャッシュ テーブルとインデックス テーブルを作成しています。保存されるデータの頻度はかなり高いため、接続プールを使用する必要があります。また、大量のデータがあるため、すべてのコミットでチェックポイントを呼び出すのではなく、50,000 行が挿入された後にデータがフラッシュされることを期待しています。つまり、.data ファイルが大きくなっているのがわかりますが、hsqldb クライアントに接続すると、テーブルとデータが表示されません。そのため、2 つの簡単なテストを行いました。1 つは単一行を挿入し、もう 1 つは新しいテーブルに 60,000 行を挿入しました。どちらの場合も、どの hsqldb クライアントでも結果を確認できませんでした。(shutdown = trueを使用することに注意してください)したがって、各コミットの後にチェックポイントを追加すると、問題が解決します。また、ログを使用するように接続文字列で指定すると、問題が解決します(ただし、本番環境ではログは必要ありません)。

したがって、接続プール内の一部の接続が閉じられていないため、データベースが変更を何らかの形でコミットしてクライアントで利用できるようにすることを妨げていると思います。では、なぜ 60,000 行でも結果が表示されないのでしょうか。また、プールが自動的に閉じられることを期待しています...何が間違っていますか? 舞台裏で何が起こっているのですか?

データ ソースを取得するコードは次のようになります。

Class.forName("org.hsqldb.jdbcDriver");
String url = "jdbc:hsqldb:" + m_dbRoot + dbName + "/db" + ";hsqldb.log_data=false;shutdown=true;hsqldb.nio_data_file=false";
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, user, password);
GenericObjectPool connectionPool = new GenericObjectPool();
KeyedObjectPoolFactory stmtPool = new GenericKeyedObjectPoolFactory(null);
new PoolableConnectionFactory(connectionFactory, connectionPool, stmtPool, null, false, true);
DataSource ds = new PoolingDataSource(connectionPool);

そして、このプールされたデータ ソースを使用してテーブルを作成しています。

Connection c = m_dataSource.getConnection();
Statement st = c.createStatement();
String script = String.format("CREATE CACHED TABLE IF NOT EXISTS %s (id %s NOT NULL, entity %s NOT NULL, PRIMARY KEY (id));", m_tableName, m_idGenerator.getIdType(), TABLE_ENTITY_TYPE);
st.execute(script);
c.close;
st.close();

行を挿入します。

Connection c = m_dataSource.getConnection();
c.setAutoCommit(false);
Statement  stmt = c.prepareStatement(m_sqlInsert);
stmt.setObject(1, id);
stmt.setBinaryStream(2, Serializer.Helper.serialize(m_serializer, entity));
stmt.executeUpdate();
stmt.close();
stmt = null;
c.commit();
c.close();
stmt.close();

したがって、上記はデータを追加しているように見えますが、表示されません。明示的に connectionPool.close(); を呼び出したとき。その時だけ、私は結果を見ることができました。JDBCDataSource も使用しようとしましたが、同様に機能しました。それで、何が起こっているのですか?そして、これを行う正しい方法は何ですか?

4

1 に答える 1

1

アプリケーション プロセスの外部からデータベースにアクセスする方法は、単純に間違っています。

ファイルデータベースに接続する Java プロセスは 1 つだけです。

目的を達成するには、まったく同じ JDBC URL を使用して、アプリケーション内で HSQLDB サーバーを起動します。次に、外部クライアントからこのサーバーに接続します。

ガイドを参照してください:

http://www.hsqldb.org/doc/2.0/guide/listeners-chapt.html#lsc_app_start

更新: OP は、アプリケーションが停止した後に外部クライアントが使用されたとコメントしました。hsqldb.log_data=false でログをオフにしたため、永続的に保持されるものはありません。アプリケーションが作業を完了したら、明示的な CHECKPOINT または SHUTDOWN を実行する必要があります。接続プールがなくても、 shutdown=true にまったく依存することはできません。

ガイドを参照してください:

http://www.hsqldb.org/doc/2.0/guide/deployment-chapt.html#dec_bulk_operations

于 2013-06-06T21:27:16.430 に答える