Данные не сохраняются должным образом в hsqldb при использовании объединенного источника данных с помощью dbcp.

Я использую hsqldb для создания кэшированных и индексированных таблиц. Сохраняемые данные имеют довольно высокую частоту, поэтому мне нужно использовать пул соединений. Кроме того, поскольку данных много, я не вызываю контрольную точку при каждой фиксации, а скорее ожидаю, что данные будут сброшены после вставки 50 000 строк. Итак, дело в том, что я вижу, что файл .data растет, но когда я подключаюсь к клиенту hsqldb, я не вижу таблиц и данных. Итак, у меня было 2 простых теста: один вставил одну строку и один вставил 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, и это тоже сработало. Так, что происходит? И как это правильно сделать?


person Sophie    schedule 06.06.2013    source источник


Ответы (1)


Ваш метод доступа к базе данных извне процесса вашего приложения просто неверен.

Предполагается, что к файлу подключается только один Java-процесс: база данных.

Чтобы достичь своей цели, запустите сервер HSQLDB в своем приложении, используя точно такой же URL-адрес JDBC. Затем подключитесь к этому серверу с внешнего клиента.

См. Руководство:

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

person fredt    schedule 06.06.2013
comment
Я подключился к внешнему клиенту только после того, как мое java-приложение уже остановилось, поэтому был один java-процесс, соединяющий db. - person Sophie; 09.06.2013
comment
Спасибо, все равно ... Так почему, когда я использовал соединение без пула, все работало (с log = false и без явной контрольной точки)? Также в документации сказано, что каждые 50000 строк фиксируются автоматически, но этого тоже не произошло. - person Sophie; 10.06.2013
comment
Он не говорит, что фиксируются каждые 50000 строк. Эта цифра представляет собой количество строк, хранящихся в кэше по умолчанию. Автоматическая контрольная точка возникает, когда в файл журнала записывается 50 МБ данных, но вы отключили журнал. shutdown=true — это, по сути, страховой механизм, а не правильный способ выключения. - person fredt; 10.06.2013
comment
хорошо, так что в моем случае использования, когда и как бы вы предложили позвонить на контрольно-пропускной пункт? может мой подход изначально не правильный? - person Sophie; 10.06.2013
comment
Вызовите CHECKPOINT или SHUTDOWN, когда закончите вставки. Это все есть в Путеводителе. - person fredt; 10.06.2013
comment
Вы выполняете CHECKPOINT так же, как вы выполняете CREATE CACHED TABLE... - person fredt; 10.06.2013