编辑:添加重新启动嵌入式Derby数据库的精度和一个可能更简单的解决方案。
我可以至少部分重现该问题,理解并解决它。但是我不能说为什么
BoneCP效果很好。我只是注意到,如果我在关闭tomcat和再次重新启动之间等待了足够的时间,它就可以工作。我想BoneCP不会立即访问数据库,而是等待足够长的时间才能建立第一个真正的连接。
首先是问题:将Derby用作嵌入式数据库时,该数据库是在第一次连接时启动的,但是必须明确关闭它。如果不是,
db.lock则不会删除该文件,并且其他应用程序可能会在再次启动数据库时遇到问题。在tomcat中或在spring(默认情况下)都不存在自动关闭此类数据库的功能。
接下来,为什么尝试使用an
EmbeddedDatabaseConfigurer无效:
EmbeddedDatabaseConfigurer不是魔术标记,并且在类中继承它不足以让spring自动使用它。它只是一个接口,必须由配置程序实现才能允许
EmbeddedDatabaseFactory使用。
终于解决了。您不应使用
SimpleDriverDataSource来从嵌入式Derby数据库获取连接,而应使用
EmbeddedDatabaseFactory。默认情况下,Spring知道Derby嵌入式数据库,您可以通过简单地设置类型来配置工厂…但是它仅适用于内存数据库,并且您有文件数据库!太简单了……您必须向工厂注入配置程序,以确保一切正常。
现在是代码(从第一个版本开始):
@Configurationpublic static class DevelopmentConfig{ EmbeddedDatabaseFactory dsFactory; public DevelopmentConfig() { EmbeddedDatabaseConfigurer configurer = new EmbeddedDatabaseConfigurer() { @Override public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { System.out.println("CONFIGURE"); properties.setDriverClass(org.apache.derby.jdbc.EmbeddedDriver.class); properties.setUrl("jdbc:derby:C:\Users\Kevin\Desktop\DerbyDB"); } @Override public void shutdown(DataSource dataSource, String databaseName) { final String SHUTDOWN_CODE = "XJ015"; System.out.println("SHUTTING DOWN"); try { DriverManager.getConnection("jdbc:derby:;shutdown=true"); } catch (SQLException e) { // Derby 10.9.1.0 shutdown raises a SQLException with pre "XJ015" if (!SHUTDOWN_CODE.equals(e.getSQLState())) { e.printStackTrace();; } } } }; dsFactory = new EmbeddedDatabaseFactory(); dsFactory.setDatabaseConfigurer(configurer); } @Bean public DataSource dataSource() throws SQLException, PropertyVetoException { System.out.println("RETURNING DATASOURCE"); return dsFactory.getDatabase(); } // remaining of pre unchanged这样,我就可以热装战争了,并且当tomcat关闭时,db.lock通常会被销毁。
编辑:如果出现问题,Derby文档建议添加以下命令以在关机后重新启动数据库:
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();。它可能是该configureConnectionProperties方法的最后一条指令。
但实际上,解决方案可能更简单。什么 真正
需要被添加到您的配置是嵌入式驱动程序(并最终重新启动)的正常关机。因此,一个简单的
PreDestroy(最终是@PostConstruct)注释方法就足够了:
@Configurationpublic static class DevelopmentConfig{ @PreDestroy public void shutdown() { final String SHUTDOWN_CODE = "XJ015"; System.out.println("SHUTTING DOWN"); try { DriverManager.getConnection("jdbc:derby:;shutdown=true"); } catch (SQLException e) { // Derby 10.9.1.0 shutdown raises a SQLException with pre "XJ015" if (!SHUTDOWN_CODE.equals(e.getSQLState())) { e.printStackTrace(); } } } @Bean public DataSource dataSource() throws SQLException, PropertyVetoException { DataSource dataSource = new SimpleDriverDataSource(new org.apache.derby.jdbc.EmbeddedDriver(), "jdbc:derby:C:\Users\Kevin\Desktop\DerbyDB", "", ""); System.out.println("RETURNING DATASOURCE"); return dataSource; } // remaining of pre unchanged这种变体的主要目的是您可以选择数据源,从
SimpleDriverDataSource到实际池。



