【发布时间】:2013-06-03 01:10:42
【问题描述】:
我正在使用 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();
所以上面似乎添加了数据,但看不到。 当我明确调用 连接池.close(); 然后,只有这样我才能看到结果。 我也尝试使用 JDBCDataSource 并且效果也很好。 那么发生了什么?这样做的正确方法是什么?
【问题讨论】:
标签: datasource connection-pooling hsqldb apache-commons-dbcp