2013-10-07 64 views
2

我的应用程序正在Hibernate中使用内存h2数据库,我注意到即使在关闭应用程序之后仍保留h2锁文件。即使我启动了应用程序,然后立即没有做任何关闭应用程序的事情,这种情况就发生了h2离开锁文件,即使只创建一个连接并立即断开连接

进一步调查显示,当我第一次开始我做一个测试连接,检查数据库是好的如下应用(退出应用程序,如果我不能连接)

try 
{ 
    Session session = HibernateUtil.getSession(); 
    Transaction t = session.getTransaction(); 
    t.setTimeout(10); 
    session.beginTransaction(); 
    t.commit(); 
    HibernateUtil.closeSession(session); 
} 
catch (Exception ex) 
{ 
    MainWindow.logger.log(Level.SEVERE, "Problem accessing database needs recreating:" + ex.getMessage(), ex); 
    System.exit(0); 
} 

删除此代码解决了这个问题该锁文件现在消失。但我不明白为什么在我结束会议时它并没有消失。问题并没有消失,因为如果我在应用程序中做了任何实际的工作,那么我仍然留下锁文件被遗留的问题。

HibernateUtil的方法

public static Session getSession() 
    { 
     if (factory == null) 
     { 
      Configuration config = 
        HibernateUtil.getInitializedConfiguration(); 
      factory = config.buildSessionFactory(); 
     } 
     Session hibernateSession = 
       factory.openSession(); 
     return hibernateSession; 
    } 

public static void closeSession(Session session) 
    { 
     if(session!=null) 
     { 
      session.close(); 
     } 
    } 

public static Configuration getInitializedConfiguration() 
    { 
     Configuration config = new Configuration(); 

     config.setProperty(Environment.DRIVER,"org.h2.Driver"); 
     config.setProperty(Environment.URL,"jdbc:h2:"+Db.DBFOLDER+"/"+Db.DBNAME+";FILE_LOCK=SOCKET;MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE;CACHE_SIZE=50000"); 
     config.setProperty(Environment.DIALECT,"org.hibernate.dialect.H2Dialect"); 
     org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider"); 
     config.setProperty("hibernate.connection.username","jaikoz"); 
     config.setProperty("hibernate.connection.password","jaikoz"); 
     config.setProperty("hibernate.c3p0.numHelperThreads","10"); 
     config.setProperty("hibernate.c3p0.min_size","20"); 
     config.setProperty("hibernate.c3p0.max_size","100"); 
     config.setProperty("hibernate.c3p0.timeout","300"); 
     config.setProperty("hibernate.c3p0.maxStatementsPerConnection","50"); 
     config.setProperty("hibernate.c3p0.idle_test_period","3000"); 
     config.setProperty("hibernate.c3p0.acquireRetryAttempts","10"); 
     config.setProperty("hibernate.show_sql","false"); 
     addEntitiesToConfig(config); 
     return config; 
    } 

我的网址连接形式

jdbc:h2:Database/Database.h2.db;FILE_LOCK=SOCKET;MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE;CACHE_SIZE=50000 

我试图将其更改为

jdbc:h2:Database/Database.h2.db;FILE_LOCK=SOCKET;MVCC=TRUE;DB_CLOSE_ON_EXIT=TRUE;CACHE_SIZE=50000 

的但没有任何效果

之所以这对我来说是一个真正的问题,是因为我有一个用户可以使用的recreateDatabase()命令,这在数据库文件重新创建之前物理删除了数据库文件,但是如果文件仍然存在,它们当然不能被删除正如它们通过锁文件的存在所证明的那样。所以recreateDatabase()命令不起作用

回答

3

您正在使用连接池。关闭连接不会实际关闭它,它只会将连接返回到池。

这意味着第一步是阅读C3P0ConnectionProvider的文档以了解它如何与c3p0对话。您需要访问ComboPooledDataSource,以便您可以拨打reset()。将min_size设置为0也可能有所帮助。

这就是说,除非您完全控制所有线程,否则这是非常危险的。如果你不这样做,那么其他线程可能想要访问数据库,就像你杀死所有连接一样。因此,如果这是一个Web应用程序,只要您重置数据库,就需要安装拒绝所有请求的筛选器。

另请注意,您并未使用内存数据库;您正在使用基于嵌入式文件的数据库。要创建内存数据库,请使用jdbc:h2:mem:

+0

谢谢,我想我已经解决了,我需要使用factory.close()关闭休眠会话工厂,并且是使用嵌入式数据库,我想说的是。 –

1

嗨,大家好,从侑本地互联网 这个错误,如果您添加的ConnectionURL 的结束你的数据库端口号将成为确定 例如 JDBC的:mysql://127.0.0.1:3307/hibernateExamples