Tomcat中的H2 SqlException在嵌入模式下被另一个进程锁定

Jua*_*cia 6 java tomcat h2

我的Web项目在Tomcat 7中运行.我的服务器提供程序已经有一个MySql服务器,但我想使用H2,因为它给了我更大的灵活性和速度.我的服务器提供商给我一个限制,说我不应该启动一个新线程,这样做会自动导致tomcat停止.我的项目处于alpha beta测试阶段,所以它已在本地进行测试.我经常被另一个进程锁定SqlException.当Tomcat更新线程池时会发生这种情况,大部分时间都是在从Eclipse自动发布时发生的(这不是交易,因为它不会在服务器上发生),但有时它会随机发生.我的应用程序不直接访问数据库,但通过一个包装器,我相信它不会产生问题,但也会阻止它发生很多.它看起来像Tomcat发送保持连接到后台的线程,任何前台线程都将失败(我的应用程序是数据库密集型).在服务器模式下打开一个连接将解决问题,但它将在一个我不大声的新进程中运行.我想保留H2,所以在我必须切换到MySql之前,我需要一个以下任何答案的解决方案:

  • 在没有Tomcat线程池冲突的情况下,我可以以某种方式连接到嵌入式H2吗?
  • 我可以在没有H2的情况下连接到服务器模式H2来创建新进程吗?

注意:我无法发布任何实际代码.我肯定不是我的申请问题.我不认为这是必要的,但我会写一个描述我的包装器如何处理连接,如果需要,但问题已经确定如上所述.

Ser*_*sta 2

编辑:构建部署步骤的精度

我无法准确重现您的问题,因为我没有 Eclipse 环境。但 :

  • H2 文档清楚地表明 H2 接受来自同一 JVM 的多个同时连接(参考:功能 - h2database 文档中的多个连接
  • 相同的文档清楚地表明 H2 不接受来自多个进程的直接连接(需要一个充当服务器,另一个使用 TCP 连接) - 这不是您关心的问题,因为您的提供商不允许您创建其他进程,但这是你错误的原因
  • 我可以做一些测试,在一个具有多个连接的进程中打开 H2 数据库(以嵌入式模式),并且可以处理同时请求(5 个连接,每个连接一个请求,一次读取 5 个结果集,每个结果集一行)
  • 我可以使用同一进程的 2 个同步线程进行类似的测试(线程 1 row1、线程 2 row1、线程 1 row2、线程 2 row2 ...)
  • 一旦数据库在另一个进程(h2console)中打开,我就会收到错误Database may be already in use: "Locked by another process"

所以我现在有充分的理由说问题的发生是因为 Eclipse 在编译部署过程中打开数据库(我知道 Netbeans 可以做到这一点...),或者因为它有一个视图允许开发人员(您)直接访问数据库(Netbeans 也可以做到这一点....)。如果应用程序在 Eclipse 关闭数据库之前启动,则可能会出现竞争条件。

由于您的生产环境中没有 Eclipse(也没有任何其他访问数据库的进程),因此这应该不是问题。

您可以通过以下简单步骤确认:

  • 在 Eclipse 下产生战争
  • 退出 Eclipse
  • 启动一个新的 Tomcat 实例(在您的开发机器上)
  • 在该实例下部署您的应用程序并优先从两个不同的浏览器连接到它,以确保至少有 2 个连接

不应发生异常。

或者,如果您习惯了,您可以使用Apache JMeter等工具对应用程序施加压力

即使 Eclipse 本身不访问数据库,在部署步骤中也可能会发生很多事情。摆脱这种情况的一个简单方法是在开发计算机中部署新版本之前仔细停止并取消部署应用程序。如果问题不再出现,则生产中应该没有问题(只要遵循这些步骤)。