在dbcp使用池化数据源时,数据未正确存储到hsqldb

时间:2013-06-06 20:57:27

标签: datasource connection-pooling hsqldb apache-commons-dbcp

我正在使用hsqldb来创建缓存表和索引表。 存储的数据频率非常高,因此我需要使用连接池。 另外因为有很多数据我不会在每次提交时调用checkpoint,而是期望在插入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,它也可以工作。 那么发生了什么?什么是正确的方法呢?

1 个答案:

答案 0 :(得分:1)

从应用程序进程外部访问数据库的方法完全错误。

只应该有一个java进程连接到该文件:database。

为了实现您的目标,请使用完全相同的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