【问题标题】:Embedded H2 + Tomcat 7 JDBC realm + Hibernate = "Locked by another process"Embedded H2 + Tomcat 7 JDBC realm + Hibernate =“被另一个进程锁定”
【发布时间】:2014-03-18 20:17:57
【问题描述】:

也许标题是不言自明的,但我正在尝试使用 H2 数据库的嵌入式实例创建一个 Web 应用程序。我将 Tomcat 7 配置为使用 JDBC 领域进行基于表单的身份验证。 server.xml 有:

<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.h2.Driver"
connectionURL="jdbc:h2:/someDir/myDB"
connectionName="userName"
connectionPassword="password"
userTable="user_enabled"
userNameCol="user_name"
userCredCol="pass"
userRoleTable="user_role"
roleNameCol="role_name" />

我也在使用 Hibernate 来实现持久性。 persistence.xml 有:

<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
<property name="hibernate.connection.url" value="jdbc:h2:/someDir/myDB" />
<property name="hibernate.connection.username" value="userName" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.show_sql" value="true" />
<property name="current_session_context_class" value="org.hibernate.context.internal.ThreadLocalSessionContext" />

如果我尝试启动我得到的服务器:

(...) Caused by: org.h2.jdbc.JdbcSQLException: Database may be already in use: "Locked by another process".

我的网络应用程序无法启动。

启动 H2 TCP 服务器并将 JDBC URL 替换为 jdbc:h2:tcp://myIP/ 工作正常。所以我的数据库文件没有问题。另外,我确信没有其他人试图使用这些文件。所以冲突只能发生在 JDBC 领域和 Hibernate 之间。

为什么需要嵌入式服务器?出于经典原因:我想分发此应用程序,并且我不希望用户必须启动两个进程而不仅仅是一个进程。此外,这不是共享数据库,因此无需为此创建新进程。最后,没有为数据库打开额外的服务器端口,这有利于安全。

【问题讨论】:

标签: java hibernate tomcat jdbc h2


【解决方案1】:

回答我自己的问题,完成这项工作的方法是使用 JNDI 数据源访问数据库。对于身份验证,应将 Tomcat 配置为使用 DataSourceRealm。因此 Tomcat 安全性和 Hibernate 都将使用相同的 H2 嵌入式实例,这不会导致我遇到的冲突。

【讨论】:

    【解决方案2】:

    虽然 JNDI 数据源更可取,但最初的问题是您尝试使用文件或嵌入式数据库 url 创建到同一个 H2 数据库的两个连接。 H2 确实支持这一点,但两个进程都需要将“;AUTO_SERVER=true”附加到连接 url。这将导致第一个连接以嵌入式模式启动正在处理的数据库,但将允许第二个连接通过 tcp ip 进行连接。

    详情请点击此处:

    http://www.h2database.com/html/features.html#auto_mixed_mode

    【讨论】:

    • 感谢您的留言。是的,这是一种可能性,但我试图避免这种可能性。拥有一个嵌入式 DB 有点奇怪,它创建一个服务器套接字,同一 JVM 上的其他进程必须连接到该套接字。这不仅可能会降低性能,而且还会不必要地打开一个 TCP 端口,这可能是一个安全问题并与其他进程竞争该端口。 AUTO_SERVER 很棒,但我想它是一个适合其他用例的功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 2021-11-11
    • 2013-05-02
    • 1970-01-01
    • 2011-12-30
    • 2023-03-21
    相关资源
    最近更新 更多