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

时间:2014-06-17 18:39:28

标签: java tomcat h2

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

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

注意:我无法发布任何实际代码。我肯定不是我的申请问题。我不认为这是必要的,但我会写一个关于我的包装如何处理连接的描述,如上所述,但问题已被识别,如上所述。

1 个答案:

答案 0 :(得分:2)

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

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

  • H2文件清楚,H2接受来自同一JVM的多个同时连接 (在h2database文档中参考:Feature - Multiple connections
  • 同样的文档很清楚,H2不接受来自多个进程的直接连接(需要一个充当服务器而另一个充当TCP连接) - 由于您的提供商不允许您创建,因此您不关心它其他流程,但这是你的错误的原因
  • 我可以在一个具有多个连接的进程中打开H2数据库(在嵌入模式下)进行一些测试,并且可以同时处理请求(5个连接,每个连接一个请求,一次读取5个结果集,每行一个)< / LI>
  • 我可以用同一进程的2个同步线程做一个类似的测试(thread1 row1,thread2 row1,thread1 row2,thread2 row2 ......)
  • 在另一个进程(h2console)中打开数据库后,我收到错误Database may be already in use: "Locked by another process"

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

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

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

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

不应发生异常。

Optionnaly,如果您已经习惯了,可以使用像Apache JMeter

这样的工具来强调应用程序

即使Eclipse本身不访问数据库,在部署步骤中也可能发生许多事情。摆脱这种情况的一种简单方法是在开发机器中部署新版本之前小心地停止和取消部署应用程序。如果问题不再发生,您应该在生产中没有问题(只要您尊重这些步骤)。