我正在使用 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 并且效果也很好。那么发生了什么?这样做的正确方法是什么?