Tomcat 带有嵌入式 H2 的 WebApp:数据库可能已在使用中:"Locked by another process"
Tomcat WebApp with embedded H2 : Database may be already in use: "Locked by another process"
我正在开发 Maven Spring 在嵌入式 H2 数据库上使用 Hibernate 启动 Web 应用程序。
该应用程序部署在 Tomcat 8 个应用程序容器上,使用来自 Maven Tomcat 插件 (tomcat7-maven-plugin) 的 Maven 目标 tomcat7:redeploy。
当我第一次尝试在 Tomcat 上部署此 Web 应用程序时,我没有出现异常(Tomcat 重启后)。
但是当我尝试在 Tomcat 上重新部署此 Web 应用程序时,出现以下异常:
org.h2.jdbc.JdbcSQLException: Database may be already in use: "Locked
by another process". Possible solutions: close all other
connection(s); use the server mode; SQL statement:
null/14cfb969fb93251ff134953c65dd1f05db2ecd34c6b [90020-145]
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:file:d:/Profiles/mBaye/Developement/Run/spring-boot-web-seed-dev/db/springbootwebui;DB_CLOSE_DELAY=0;MVCC=TRUE</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!-- <property name="hbm2ddl.auto">create</property> -->
<!-- Update the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="app/Greeting.hbm.xml"/>
</session-factory>
</hibernate-configuration>
GreetingController.java
@Controller
public class GreetingController {
private static Logger logger ;
// A SessionFactory is set up once for an application
private static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
[...]
private Greeting saveGreeting(Greeting greeting) {
logger.info(new StringBuilder("greeting=").append(greeting.toString()).toString());
Session session = null;
Greeting ret = null;
try {
session = sessionFactory.openSession();
session.beginTransaction();
session.save( greeting );
session.getTransaction().commit();
// Return result
ret = greeting ;
} catch (Exception e) {
logger.log(Level.SEVERE, new StringBuilder("Failed to save ").append(greeting.toString()).toString(), e);
} finally {
session.close();
}
if (ret != null) {
logger.info(new StringBuilder("ret=").append(ret.toString()).toString());
} else {
logger.info(new StringBuilder("ret=null").toString());
}
return ret ;
}
[...]
}
我在其他主题上读到,当 VM 正确退出时,数据库连接会自动关闭
(来源:What is the proper way to close H2?)
我想,当应用程序部署在 Tomcat 上时,数据库连接由 Tomcat 保持。
我想找到一种正确的方法来关闭 Tomcat 重新部署时的所有数据库连接。
提前致谢。
H2 在所有连接关闭时关闭数据库。关闭来自连接池的所有连接对我有用。
我终于找到了解决办法! :)
我将 H2 数据库连接的设置 URL 更改为:
<property name="connection.url">jdbc:h2:file:d:/Profiles/mBaye/Developement/Run/spring-boot-web-seed-dev/db/springbootwebui;MVCC=TRUE;DB_CLOSE_ON_EXIT=TRUE;FILE_LOCK=NO</property>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:file:d:/Profiles/mBaye/Developement/Run/spring-boot-web-seed-dev/db/springbootwebui;MVCC=TRUE;DB_CLOSE_ON_EXIT=TRUE;FILE_LOCK=NO</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!-- <property name="hbm2ddl.auto">create</property> -->
<!-- Update the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="app/Greeting.hbm.xml"/>
</session-factory>
</hibernate-configuration>
我不确定这是最好的解决方案,但它确实有效。
关闭连接对我也有效,在没有意识到的情况下打开了多个连接。
我正在开发 Maven Spring 在嵌入式 H2 数据库上使用 Hibernate 启动 Web 应用程序。 该应用程序部署在 Tomcat 8 个应用程序容器上,使用来自 Maven Tomcat 插件 (tomcat7-maven-plugin) 的 Maven 目标 tomcat7:redeploy。
当我第一次尝试在 Tomcat 上部署此 Web 应用程序时,我没有出现异常(Tomcat 重启后)。
但是当我尝试在 Tomcat 上重新部署此 Web 应用程序时,出现以下异常:
org.h2.jdbc.JdbcSQLException: Database may be already in use: "Locked by another process". Possible solutions: close all other connection(s); use the server mode; SQL statement: null/14cfb969fb93251ff134953c65dd1f05db2ecd34c6b [90020-145]
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:file:d:/Profiles/mBaye/Developement/Run/spring-boot-web-seed-dev/db/springbootwebui;DB_CLOSE_DELAY=0;MVCC=TRUE</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!-- <property name="hbm2ddl.auto">create</property> -->
<!-- Update the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="app/Greeting.hbm.xml"/>
</session-factory>
</hibernate-configuration>
GreetingController.java
@Controller
public class GreetingController {
private static Logger logger ;
// A SessionFactory is set up once for an application
private static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
[...]
private Greeting saveGreeting(Greeting greeting) {
logger.info(new StringBuilder("greeting=").append(greeting.toString()).toString());
Session session = null;
Greeting ret = null;
try {
session = sessionFactory.openSession();
session.beginTransaction();
session.save( greeting );
session.getTransaction().commit();
// Return result
ret = greeting ;
} catch (Exception e) {
logger.log(Level.SEVERE, new StringBuilder("Failed to save ").append(greeting.toString()).toString(), e);
} finally {
session.close();
}
if (ret != null) {
logger.info(new StringBuilder("ret=").append(ret.toString()).toString());
} else {
logger.info(new StringBuilder("ret=null").toString());
}
return ret ;
}
[...]
}
我在其他主题上读到,当 VM 正确退出时,数据库连接会自动关闭 (来源:What is the proper way to close H2?)
我想,当应用程序部署在 Tomcat 上时,数据库连接由 Tomcat 保持。
我想找到一种正确的方法来关闭 Tomcat 重新部署时的所有数据库连接。
提前致谢。
H2 在所有连接关闭时关闭数据库。关闭来自连接池的所有连接对我有用。
我终于找到了解决办法! :)
我将 H2 数据库连接的设置 URL 更改为:
<property name="connection.url">jdbc:h2:file:d:/Profiles/mBaye/Developement/Run/spring-boot-web-seed-dev/db/springbootwebui;MVCC=TRUE;DB_CLOSE_ON_EXIT=TRUE;FILE_LOCK=NO</property>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:file:d:/Profiles/mBaye/Developement/Run/spring-boot-web-seed-dev/db/springbootwebui;MVCC=TRUE;DB_CLOSE_ON_EXIT=TRUE;FILE_LOCK=NO</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!-- <property name="hbm2ddl.auto">create</property> -->
<!-- Update the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="app/Greeting.hbm.xml"/>
</session-factory>
</hibernate-configuration>
我不确定这是最好的解决方案,但它确实有效。
关闭连接对我也有效,在没有意识到的情况下打开了多个连接。