0

Я использую hsqldb для создания кэшированных таблиц и индексированных таблиц. Сохраняемые данные имеют довольно высокую частоту, поэтому мне нужно использовать пул соединений. Также из-за большого количества данных я не вызываю контрольную точку при каждом фиксации, а скорее ожидаю, что данные будут сброшены после того, как будут вставлены 50 000 строк. Итак, я вижу, что файл .data растет, но когда я подключаюсь к клиенту hsqldb, я не вижу таблицы и данные. Итак, у меня было 2 простых теста, один вставил одну строку и один вставил 60 000 строк в новую таблицу. В обоих случаях я не мог видеть результат в любом клиенте hsqldb. (Обратите внимание, что я использую shutdown = true) Итак, когда я добавляю контрольную точку после каждой фиксации, она решает проблему. Также, если в строке подключения используется журнал, он решает проблему (я не хочу, чтобы журнал работал, хотя). Кроме того, не используя объединенное соединение, проблема решена, и в последнее время используется объединенный источник данных и явно закрывается до выключения.Данные хранятся неправильно в hsqldb при использовании пула данных dbcp

Таким образом, я предполагаю, что некоторые соединения в пуле соединений не закрываются, что препятствует тому, чтобы db каким-то образом фиксировала изменения и делала их доступными для клиента. Но тогда почему я не мог увидеть результат даже с 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, и он тоже работал. Так что же происходит? И каков правильный способ сделать это?

ответ

1

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

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

Для достижения вашей цели запустите сервер 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

+0

Я связан с внешним клиентом только после того, как мой Java приложение уже остановился, так что был один процесс Java подключения дб. – Sophie

+0

Спасибо, все же ... Так почему, когда я использовал соединение без объединения, все работало (с log = false и без явной контрольной точки)? Также в документации говорится, что каждые 50000 строк фиксируются автоматически, но этого также не произошло. – Sophie

+0

Он не говорит, что все 50000 строк совершены. Это число по умолчанию - количество строк, хранящихся в кеше. Автоматическая контрольная точка происходит, когда 50 МБ данных записывается в файл .log, но вы отключили журнал. Shutdown = true - это в основном механизм страхования, а не правильный способ отключения. – fredt